如何压缩不同长度的列表?

zer*_*iel 11 haskell

我怎么能zip两个像

["Line1","Line2","Line3"]
["Line4","Line5"]
Run Code Online (Sandbox Code Playgroud)

不丢弃第一个列表中的休息元素?

如果可以的话,我想用空列表压缩额外的元素.

Zet*_*eta 11

zipWithPadding :: a -> b -> [a] -> [b] -> [(a,b)]
zipWithPadding a b (x:xs) (y:ys) = (x,y) : zipWithPadding a b xs ys
zipWithPadding a _ []     ys     = zip (repeat a) ys
zipWithPadding _ b xs     []     = zip xs (repeat b)
Run Code Online (Sandbox Code Playgroud)

只要有元素,我们就可以简单地压缩它们.一旦我们用完了元素,我们只需用填充元素的无限列表压缩剩余的列表.

在您的情况下,您将使用它作为

zipWithPadding "" "" ["Line1","Line2","Line3"] ["Line4","Line5"]
-- result: [("Line1","Line4"),("Line2","Line5"),("Line3","")]
Run Code Online (Sandbox Code Playgroud)

  • 注意那些想看"mempty"或"Monoid"的人:`zipWithPadding mempty mempty`会给你你的`(Monoid a,Monoid b)=> [a] - > [b] - > [(a,b) ]`. (3认同)

Rei*_*ite 8

另一种解决方案是制作一个zip函数,该函数适用于monoid并使用mempty填充缺失值:

import Data.Monoid

mzip :: (Monoid a, Monoid b) => [a] -> [b] -> [(a, b)]
mzip (a:as) (b:bs) = (a, b) : mzip as bs
mzip []     (b:bs) = (mempty, b) : mzip [] bs
mzip (a:as) []     = (a, mempty) : mzip as []
mzip _      _      = []

> mzip ["Line1","Line2","Line3"] ["Line4","Line5"]
[("Line1","Line4"),("Line2","Line5"),("Line3","")]
Run Code Online (Sandbox Code Playgroud)

  • @Riccardo我不会说它更好,接受的答案将适用于你不一定有"Monoid"的情况,并且可能想要为不同的拉链使用不同的默认值.数据可能不具有"<>"的良好含义,但仍然具有理智的"mempty"(或多个合理的默认值).Haskell中的最佳实践表示使用可能性最小的类型,使用`Monoid`限制此函数的次数超过必要,因为不使用`<>`.此外,`mzip`可以通过将`mempty`传递给两个默认值来定义`zipWithPadding`. (2认同)