在Elm中,您如何获得列表中的每个偶数索引并返回另一个列表?

时间:2016-11-27 06:38:20

标签: elm

在Elm中,你如何获得列表中的每个偶数索引并返回另一个列表?

2 个答案:

答案 0 :(得分:4)

大多数情况下,您不需要编写递归函数,因为您可以使用标准辅助函数来为您执行此操作。以下是针对您的具体问题的解决方案:

takeEvenIndexes : List a -> List a
takeEvenIndexes l =
  l
  |> List.indexedMap (\ i x -> if i % 2 == 0 then Just x else Nothing)
  |> List.filterMap identity

indexedMap函数类似于map,但您也可以依赖于值的索引。 filterMap就像一张地图,但您可以通过返回Nothing来放弃一些值。这里它被应用于identity函数,因为过滤已经在前一行预先计算过了。

答案 1 :(得分:2)

所以你想只从列表中返回偶数索引的项目,对吗?

在这里,您可以如何编写自己的功能。我们将编写一个辅助函数everySecond_,看起来像这样。

everySecond_ : List a -> Int -> List a
everySecond_ list index =
    case list of
        [] ->
            []

        hd :: tl ->
            if index % 2 == 0 then
                hd :: (everySecond_ tl (index + 1))
            else
                everySecond_ tl (index + 1)

此函数采用一个列表,以及一个数字,表示该列表当前头的索引。我们需要将它作为参数传递给函数。

然后我们在列表上进行模式匹配。如果它为空,我们返回一个空列表;这标志着递归的结束。列表中的最后一个元素始终是一个空列表。如果它的不是是一个空列表,我们采用头部(第一个元素)和尾部(表示一切的列表)。

如果我们的index参数是偶数(% 2 == 0表示"当除以2时,不留下余数"),我们要保留此元素,因此我们将其附加到我们正在建立的列表的前面,并通过使用当前列表的尾部和递增的索引号再次调用everySecond_来继续构建。

如果它,我们不想保留此元素,因此我们只返回everySecond_ tl (index + 1),列表的下一个阶段,以及过程重复。

这就是它的逻辑。但这意味着我们需要调用everySecond_ [foo, bar, baz] 1来使用我们的函数,总是将1作为默认参数传入。这不直观。这就是为什么我们用一个下划线称它为everySecond_ - 这不是我们要让人们调用的东西,这是一个辅助功能,它将在后面存在场景。我们可以将其隐藏在

之后
everySecond : List a -> List a
everySecond list =
    everySecond_ list 1

现在你调用everySecond [foo, bar, baz]并且它工作正常,基本上将起始索引默认为1.

更简单的方法是根本不跟踪索引,而是使用布尔值(True / False)。你从一个False开始,而不是用2来测试可分性,你只需检查布尔值。如果它为True,则保留元素,并使用False再次调用该函数;如果它为False,则忽略该元素并使用True再次调用该函数。