【问题标题】:split elements into groups haskell将元素分成组 haskell
【发布时间】:2014-10-26 09:34:15
【问题描述】:

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

我完全陷入了困境! 请帮帮我!

【问题讨论】:

    标签: list haskell indexing split


    【解决方案1】:

    Data.Lists.Split 中有一个很棒的函数,名为 chunksOf,它使用参数 2 会从列表中拉出对。 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]]
    

    【讨论】:

      【解决方案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不是_|_splitAt _|_ xs = _|_)时,它相当于(take n xs, drop n xs)

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

      【讨论】:

      • chunks n = takeWhile (not.null) . unfoldr (Just . splitAt n)。或unfoldr (list Nothing (Just . splitAt n))list e ne xs = case xs of [] -&gt; e; _ -&gt; ne xs。 ("list"maybe 类比)。 :)
      【解决方案3】:

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

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

      在开始实施之前,先看看是否有人这样做过:

      • Hoogle 给出了很多相似的结果,但没有一个真正匹配。
      • Hayoo 表明该函数已在很多库中实现,但实际上只是作为本地助手。

      如果你想自己做,你应该从 splitAt 开始(从 one 前缀中分离出来),然后在剩下的时候继续做:

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

      【讨论】:

        【解决方案4】:

        您可以自己为此编写一个函数:

        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"]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多