Elm 中的列表拆分

问题描述

编写一个函数一个列表分成两个列表。第一部分的长度由调用者指定。

我是 Elm 的新手,所以我不确定我的推理是否正确。我认为我需要转换数组中的输入列表,以便我能够按提供的输入数字对其进行切片。我也在语法上有点挣扎。到目前为止,这是我的代码

listSplit: List a -> Int -> List(List a)
listSplit inputList nr = 
let myArray = Array.fromList inputList
    in Array.slice 0 nr myArray 

所以我想返回一个包含 2 个列表(指定长度的第一个)的列表,但我被语法困住了。我该如何解决这个问题?

解决方法

替代实现:

split : Int -> List a -> (List a,List a)
split i xs =
    (List.take i xs,List.drop i xs) 

,

使用List.foldl

split : Int -> List a -> (List a,List a)
split i xs =
  let
    f : a -> (List a,List a) -> (List a,List a)
    f x (p,q) =
      if List.length p >= i then
        (p,q++[x])
      else
        (p++[x],q)
  in
    List.foldl f ([],[]) xs
  • 当列表 p 达到所需长度时,将元素 x 附加到第二个列表 q
  • 将元素 x 附加到列表 p 否则。

通常在 Elm 中,您使用 List 表示一系列值。 Array 专门用于快速索引访问。

在函数式编程中处理列表时,请尝试从 mapfilterfold 的角度考虑。它们应该就是您所需要的。

要返回一对东西(例如两个列表),请使用元组。 Elm 最多支持三个元素的元组。

此外,splitAt 包中有一个函数 List.Extra 可以做完全相同的事情,尽管为了学习目的最好自己编写。

,

我将尝试一个简单的递归定义,因为学习函数式编程的很大一部分是理解递归(foldl 只是对递归的抽象):

split : Int -> List a -> (List a,List a)
split splitPoint inputList =
    splitHelper splitPoint inputList []

{- We use a typical trick here,where we define a helper function 
that requires some additional arguments. -}
splitHelper : Int -> List a -> List a -> (List a,List a)
splitHelper splitPoint inputList leftSplitList =
     case inputList of
         [] ->
             -- This is a base case,we end here if we ran out of elements
             (List.reverse leftSplitList,[])

         head :: tail ->
              if splitPoint > 0 then
                    -- This is the recursive case
                    -- Note the typical trick here: we are shuffling elements
                    -- from the input list and putting them onto the
                    -- leftSplitList.
                    -- This will reverse the list,so we need to reverse it back
                    -- in the base cases
                    splitHelper (splitPoint - 1) tail (head :: leftSplitList)
               else
                    -- here we got to the split point,-- so the rest of the list is the output
                    (List.reverse leftSplitList,inputList)