For example if we have two strings "abc"
and "1234"
i want result "abc4"
(the first string masks second). (If we draw them vertical it's like a wave comes from left and tuch chars)
"a" "1" "a"
wave -> "b" "2" result "b"
"c" "3" "c"
"4" "4"
I start with this solution with Haskell
slice from to xs = take (to - from 1) (drop from xs)
merge l1 l2 = if length l2 > length l1
then l1 slice (length l1) (length l2) l2
else l1
Can you please provide some more elegant\compact solutions.
CodePudding user response:
You just need a special merge function
> let merge [] ys = ys
| merge xs [] = xs
| merge (x:xs) (y:ys) = x : merge xs ys
or using drop
> let merge2 x y = x drop (length x) y
CodePudding user response:
You want kind of a "zipLongest
", and transpose
is kind of like that:
maskMerge1 :: [b] -> [b] -> [b]
maskMerge1 as bs = map head $ transpose [as,bs]
-- or:
-- head <$> transpose [as,bs]
This is pretty compact and elegant (with big thanks to @leftaroundabout for the comments!).
Looking from above,
"abc" ['a' ,'b' ,'c' ]
"1234" ['1' ,'2' ,'3' ,'4']
-------- ------------------
["a1","b2","c3","4"]
-------- ------------------
"abc4" ['a' ,'b' ,'c' ,'4']
The code with length
in the other answer also works, and even for an infinite x
despite calling the dreaded length
on it, but it will retain the whole of x
in memory because of calling the length
on it.