Elm中的列表拆分

Elm中的列表拆分,elm,Elm,编写一个函数,将一个列表拆分为两个列表。第一部分的长度由调用方指定。 我是Elm的新手,所以我不确定我的推理是否正确。我认为我需要转换数组中的输入列表,以便能够根据提供的输入编号对其进行切片。我在语法方面也有点困难。以下是我目前的代码: listSplit: List a -> Int -> List(List a) listSplit inputList nr = let myArray = Array.fromList inputList in Array.slice

编写一个函数,将一个列表拆分为两个列表。第一部分的长度由调用方指定。

我是Elm的新手,所以我不确定我的推理是否正确。我认为我需要转换数组中的输入列表,以便能够根据提供的输入编号对其进行切片。我在语法方面也有点困难。以下是我目前的代码:

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

因此,我想返回一个包含2个列表的列表(指定长度的第一个列表),但我仍然停留在语法上。如何解决此问题?

使用
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
作为值序列<代码>数组专门用于快速索引访问

在函数式编程中处理列表时,试着从
映射
过滤器
折叠
的角度来考虑。它们应该是你所需要的

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


此外,软件包中还有一个功能可以做完全相同的事情,不过为了学习的目的,最好自己滚动。

替代实现:

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


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


谢谢你的帮助和解释。还有一个问题,例如,当从列表中删除第n个元素时,数组是否更方便?但是数组没有
remove
功能。在一个位置上进行
get
set
更重要。我认为,对于初学者来说,你最好忽略数组,用列表做所有事情,让自己熟悉基本知识。对于初学者来说,阵列的感知效率并不重要。还请注意,此解决方案的复杂度界限比其他解决方案更差。这是O(n²),而其他解决方案是O(m),其中n是输入列表的长度,m是拆分大小(m)。此实现的性能配置类似于take/drop实现。它的优点是作为尾部递归实现,可以编译为非常高效的白循环。
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)