在haskell中细分列表

时间:2011-12-30 15:14:24

标签: haskell

如何在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]]

7 个答案:

答案 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之后。