将元素拆分成组haskell

时间:2014-09-02 07:24:33

标签: list haskell indexing split

嘿,我是函数式编程和学习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 ..

我完全被困在这! 请帮帮我!

4 个答案:

答案 0 :(得分: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"]

答案 1 :(得分: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 = _|_

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

答案 2 :(得分:2)

首先在提出这样的问题时,请指定您想要的类型签名!因此,您希望从平面列表中创建(给定一个常量子列表长度)整个列表列表。这表明签名

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

在你开始实施之前,很聪明地看看以前是否有人这样做过:

  • Hoogle提供了大量类似的结果,但没有一个真正匹配。
  • Hayoo表明该函数已经在很多库中实现,但实际上只是作为本地帮助器。

如果你想自己动手,你应该从splitAt开始(它将一个前缀分开)并继续进行,同时保留任何内容:

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

答案 3 :(得分:0)

在名为chunksOf Data.Lists.Split 中有一个很棒的功能,它具有参数2 wiLL从列表中拉出的对。 chunksOf会将最后一个奇数元素从列表中拉出来。假设有3个元素,它将在列表中产生2个和1个元素。

以下配对功能还从列表中拉出最后一个落后者。

 pairs = takeWhile (not.null) . map (take 2) . iterate (drop 2)

我认为以下情况更好。它是为对设置的,但可以参数化以执行任何大小的块。它将采用任何列表并包含单个元素。

np ls = [take 2 (drop a ls)|a<-[0,2..(length ls)-1]]