如何获取Elm中Array / List中给定元素的第一个索引?

时间:2015-11-10 08:04:10

标签: arrays list elm

在Javascript中,可以使用indexOf来获取数组中给定元素的第一个实例。

榆树最好的方法是什么?

array = Array.fromList ["Stack","Overflow","is","","awesome"]
element = ""

indexOf element array =
  -- should return 3

如果我们有一个列表而不是一个数组怎么办?

4 个答案:

答案 0 :(得分:7)

有第三方模块elm-list-extra提供此功能。 " elemIndex" (适用于0.19)。

这个用于< 0.19 elemIndex

答案 1 :(得分:6)

只是为了好玩,这里是List的手动滚动版本:

helper : List a -> a -> Int -> Int
helper lst elem offset = 
  case lst of
    []      -> -1
    x :: xs ->
      if x == elem then offset
      else helper xs elem (offset + 1)

indexOf lst element =
  helper lst element 0

helper以递归方式在列表中搜索元素,跟踪到目前为止我们访问过的元素数量。对于空列表,它返回-1。 如果您不喜欢魔法常量,则可以轻松地将返回类型更改为Maybe Int并返回Nothing

这是一个使用它的完整程序(只需复制+粘贴到elm-lang.org的在线REPL中:

import Html exposing (text)

lst = ["Stack","Overflow","is","","awesome"]
element = ""

helper : List a -> a -> Int -> Int
helper lst elem offset = 
  case lst of
    []      -> -1
    x :: xs ->
      if x == elem then offset
      else helper xs elem (offset + 1)

indexOf lst element =
  helper lst element 0

main =
  text (toString (indexOf lst ""))    

答案 2 :(得分:2)

构成核心库函数的另一种观点。我发现这比递归更具可读性,更具说明性;它只是一个简单的数据转换管道。数据结构是最后一个参数,因此您可以部分应用您要查找的值,例如idxOfFoo = firstIndexOf "foo"

indicesOf : a -> List a -> List Int
indicesOf thing things =
  things
  |> List.indexedMap (,)
  |> List.filter (\(idx, item) -> item == thing)
  |> List.map fst


firstIndexOf : a -> List a -> Int
firstIndexOf thing things =
  indicesOf thing things
  |> List.minimum
  |> Maybe.withDefault -1


lastIndexOf : a -> List a -> Int
lastIndexOf thing things =
  indicesOf thing things
  |> List.maximum
  |> Maybe.withDefault -1

REPL会议:

> things = ["foo", "bar", "bat", "foo", "baz"]
["foo","bar","bat","foo","baz"] : List String
>
> firstIndexOf "foo" things
0 : Int
>
> lastIndexOf "foo" things
3 : Int
>

乍一看,我认为这与CircuitHub在List.Extra中的实现相似。

答案 3 :(得分:0)

代码

indexOf : a -> Array a -> Int 
indexOf element array =
    let
        item =
            array
                |> Array.toIndexedList                       
                |> List.filter (\tuple -> isElement tuple element)
                |> List.head
                
    in
        case item of 
            Just value ->
                Tuple.first value
            Nothing ->
                -1

isElement : (Int, a) -> a -> Bool
isElement tuple element =    
    Tuple.second tuple == element

用法

list =
    [ "a"
    , "b"
    , "c"
    ]        

index =
    list
        |> Array.fromList
        |> indexOf "b"