Haskell:合并一个列表,其中偶数索引来自列表 1,奇数来自列表 2。如果大小不同,则用 0 填充
Haskell: Merging a list where even indices are from list 1 and odd are from list 2. Fill with 0's if not the same size
我尝试创建一个 Haskell 函数,将 2 个列表合并为一个列表,其中新列表中的偶数索引来自列表 1,奇数索引来自列表 2。用 0 填充如果大小不一样。
例如:
[1] [10,15,20] => [1,10,0,15,0,20]
[2,3] [4,5] => [2,4,3,5]
我尝试创建了几个版本,但没有成功。
我怎样才能创建这样的东西?
有一个 interleave
函数,可以做类似的事情,但不完全是那样。它 'merges' 列出直到其中一个结束。
所以你可以自己写那个函数:
merge :: [Int] -> [Int] -> [Int]
merge (x:xs) (y:ys) = x : y : merge xs ys
merge (x:xs) [] = x : 0 : merge xs []
merge [] (y:ys) = 0 : y : merge [] ys
merge _ _ = []
当我们两边都有一些元素的时候,我们就把它们都拿走。当其中一个元素不存在时,我们取 0 代替它。在所有其他情况下(这是 merge [] []
情况)我们以递归和 return 一个空列表结束。
我们还可以稍微概括我们的函数以支持任何类似数字的类型:
merge :: Num a => [a] -> [a] -> [a]
merge (x:xs) (y:ys) = x : y : merge xs ys
merge (x:xs) [] = x : 0 : merge xs []
merge [] (y:ys) = 0 : y : merge [] ys
merge _ _ = []
此外,我们可以更进一步,使用 Data.Default 包中的 def
来获取我们类型的默认值,因此我们不仅可以将此函数用于数字列表:
import Data.Default
merge :: Default a => [a] -> [a] -> [a]
merge (x:xs) (y:ys) = x : y : merge xs ys
merge (x:xs) [] = x : def : merge xs []
merge [] (y:ys) = def : y : merge [] ys
merge _ _ = []
使用 this answer of mine, using the transpose :: [[a]] -> [[a]]
函数的想法,
interweaveWith :: a -> [a] -> [a] -> [a]
interweaveWith def xs ys =
-- 0 [1] [10,15,20] => [1,10,0,15,0,20]
concat $
zipWith const
(transpose [ xs ++ repeat def, -- no limit, padded with def
ys ++ repeat def ])
(transpose [xs, ys]) -- as long as the longest
我尝试创建一个 Haskell 函数,将 2 个列表合并为一个列表,其中新列表中的偶数索引来自列表 1,奇数索引来自列表 2。用 0 填充如果大小不一样。
例如:
[1] [10,15,20] => [1,10,0,15,0,20]
[2,3] [4,5] => [2,4,3,5]
我尝试创建了几个版本,但没有成功。
我怎样才能创建这样的东西?
有一个 interleave
函数,可以做类似的事情,但不完全是那样。它 'merges' 列出直到其中一个结束。
所以你可以自己写那个函数:
merge :: [Int] -> [Int] -> [Int]
merge (x:xs) (y:ys) = x : y : merge xs ys
merge (x:xs) [] = x : 0 : merge xs []
merge [] (y:ys) = 0 : y : merge [] ys
merge _ _ = []
当我们两边都有一些元素的时候,我们就把它们都拿走。当其中一个元素不存在时,我们取 0 代替它。在所有其他情况下(这是 merge [] []
情况)我们以递归和 return 一个空列表结束。
我们还可以稍微概括我们的函数以支持任何类似数字的类型:
merge :: Num a => [a] -> [a] -> [a]
merge (x:xs) (y:ys) = x : y : merge xs ys
merge (x:xs) [] = x : 0 : merge xs []
merge [] (y:ys) = 0 : y : merge [] ys
merge _ _ = []
此外,我们可以更进一步,使用 Data.Default 包中的 def
来获取我们类型的默认值,因此我们不仅可以将此函数用于数字列表:
import Data.Default
merge :: Default a => [a] -> [a] -> [a]
merge (x:xs) (y:ys) = x : y : merge xs ys
merge (x:xs) [] = x : def : merge xs []
merge [] (y:ys) = def : y : merge [] ys
merge _ _ = []
使用 this answer of mine, using the transpose :: [[a]] -> [[a]]
函数的想法,
interweaveWith :: a -> [a] -> [a] -> [a]
interweaveWith def xs ys =
-- 0 [1] [10,15,20] => [1,10,0,15,0,20]
concat $
zipWith const
(transpose [ xs ++ repeat def, -- no limit, padded with def
ys ++ repeat def ])
(transpose [xs, ys]) -- as long as the longest