2014-09-02 105 views
1

嘿我新功能编程和学习haskell。
我想知道我是否能够拆分列表中的元素并将它们分组到两个列表中。将元素拆分成组haskell

我已经看到了splitAt操作,而且只在拆分指定索引值/位置

splitAt 3 [1,2,3,4,5] -> [1,2,3][4,5]

现在,我不知道说我有一个列表,其中随机字符[A,S,D,F,G,H,J,K,U,Y,R,E,W,V,B,N], 我想这种分裂作为[A,S][D,F][G,H][J,K].... and so on ..

我完全陷入了这个! 请帮我一把!

回答

5

您可以编写一个函数,该函数自己:

mySplit :: Int -> [a] -> [[a]] 
mySplit n [] = [] 
mySplit n xs = (take n xs):(mySplit n (drop n xs)) 

演示:

λ> mySplit 2 [1,2,3,4,5,6] 
[[1,2],[3,4],[5,6]] 
λ> mySplit 2 [1,2,3,4,5,6,7] 
[[1,2],[3,4],[5,6],[7]] 

另一种方法是使用split包:

λ splitEvery 3 ['a'..'z'] 
["abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"] 
2

您也可以继续要使用splitAt,您只需手动递归:

chunks :: Int -> [a] -> [[a]] 
chunks n [] = [] 
chunks n xs = head : (chunks n tail) 
    where (head, tail) = splitAt n xs 

λ> chunks 2 [1,2,3,4,5]) 
[[1,2],[3,4],[5]] 

我想这可能是更有效的(避免了需要评估takedrop明确),但根据documentation for Data.List

当n不_|_它等同于(take n xs, drop n xs)splitAt _|_ xs = _|_ )。

我想总有不止一种方法可以做到!看看每个答案如何使用不同的模式匹配方法很有趣。

+0

'块N = takeWhile(不。空值) 。 unfoldr(Just。splitAt n)'。或'unfoldr(list Nothing(Just。splitAt n))''list e ne xs = case xs of [] - > e; _ - > ne xs'。 ([ “'list'”](http://hayoo.fh-wedel.de/?query=t+-%3E+%28 [T1] + - %3E + T%29 + - %3E + [T1] + - %3E + t)与'maybe'类似)。 :) – 2014-09-03 09:42:25

2

首先当问这样一个问题时,指定你想要的类型签名!所以你想从平面列表中创建(给定一个不变的子列表长度)整个列表。这表明签名

splitOfLen :: Int -> [a] -> [[a]] 

你开始实施之前,这是聪明,看看是否有人做过那样的事:

  • Hoogle给出一大堆的类似的结果,但真正匹配没有。
  • Hayoo显示该函数已经在很多库中实现,但实际上只是作为本地帮助程序。

如果你想自己做,你应该splitAt开始(分裂出一个前缀)和进度要做到这一点,而什么仍然是:

splitsOfLen l xs = case splitAt l xs of 
    (p, []) -> [p] 
    (p, r) -> p : splitsOfLen l r