2014-09-02 71 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