如何在haskell中将列表分组为长度相等的较小列表(最后一个子列表除外)?
E.g。
sublist 3 [1,2,3,4,5,6,7,8] -> [[1,2,3],[4,5,6],[7,8]]
sublist 2 [4,1,6,1,7,3,5,3] -> [[4,1],[6,1],[7,3],[5,3]]
答案 0 :(得分:22)
尝试:
import Data.List.Split
> splitEvery 2 [4,1,6,1,7,3,5,3]
[[4,1],[6,1],[7,3],[5,3]]
答案 1 :(得分:9)
如果您想坚持前奏,可以使用splitAt
将其删除。
splitEvery _ [] = []
splitEvery n list = first : (splitEvery n rest)
where
(first,rest) = splitAt n list
答案 2 :(得分:8)
s
模块具有Data.List.Split
功能:
chunksOf
它似乎默认安装在我的机器上,但您可能需要使用cabal。
答案 3 :(得分:6)
我喜欢的另一个解决方案是:
splitEvery :: Int -> [a] -> [[a]]
splitEvery n = takeWhile (not.null) . map (take n) . iterate (drop n)
答案 4 :(得分:2)
又一个解决方案:
split :: Int -> [a] -> [[a]]
split n = unfoldr (\s -> if null s then Nothing else Just $ splitAt n s)
答案 5 :(得分:0)
我知道这已经过时了,但是因为这对于Haskell相当新的人来说似乎是一个帖子,我觉得我也想发布我的解决方案。我试图通过仅使用Prelude来解决这个问题:
sublist :: Int -> [a] -> [[a]]
sublist n ls
| n <= 0 || null ls = []
| otherwise = take n ls:sublist n (drop n ls)
测试
sublist 3 [1,2,3,4,5,6] -- λ> [[1,2,3], [4,5,6]]
sublist 5 [1,2,3] -- λ> [[1,2,3]]
sublist (-1) [1,2,3] -- λ> []
sublist 20 [] -- λ> []
答案 6 :(得分:0)
此列表理解使用尾部。由于第一个集合以1开头,因此所有后续子集都以奇数开头。
ts n ls = [take n l|l<-init$tails ls,odd (head l)]
n
是子列表的大小,ls
是源列表。
下一个将采用任何列表并包含不匹配的元素。它被设置为仅进行配对。很明显,如何将其参数化以执行任何块大小。
np ls = [take 2(drop a ls)| a&lt; - [0,2 ..(length ls)-1]]
只需添加n
作为参数,并替换公式中的2个,一个在take
之后,一个在0
之后。