web-dev-qa-db-ja.com

elmでインデックスによってリストアイテムを取得するにはどうすればよいですか?

リストを取得しましたが、n番目のアイテムが必要です。 Haskellでは!!ですが、そのElmバリアントは見つかりません。

24
11684

Elmにはこれに相当するものはありません。もちろん、自分で実装することもできます。

(注:これは「合計」関数ではないため、インデックスが範囲外の場合は例外が発生します)。

infixl 9 !!
(!!) : [a] -> Int -> a
xs !! n  = head (drop n xs)

より良い方法は、多分データ型を使用して、合計関数を定義することです。

infixl 9 !!
(!!) : [a] -> Int -> Maybe a
xs !! n  = 
  if | n < 0     -> Nothing
     | otherwise -> case (xs,n) of
         ([],_)    -> Nothing
         (x::xs,0) -> Just x
         (_::xs,n) -> xs !! (n-1)
14
Daniël Heres

Elmは .12.1 に配列を追加し、実装は0.19で正確性とパフォーマンスを改善するために大幅にオーバーホールされました。

import Array

myArray = Array.fromList [1..5]

myItem = Array.get 2 myArray

配列のインデックスはゼロです。現在、負のインデックスはサポートされていません(私は知っています)。

ご了承ください myItem : Maybe Int。 Elmはランタイムエラーを回避するためにできる限りのことを行うので、範囲外のアクセスは明示的なNothingを返します。

頭と尾をとるのではなく、リストにインデックスを付けることを考えている場合は、配列の使用を検討してください。

配列ドキュメント

35
mgold

私はこれを使用しました:

(!!): Int -> List a -> Maybe a

(!!) index list =                          -- 3 [ 1, 2, 3, 4, 5, 6 ]

   if  (List.length list) >= index then

        List.take index list               -- [ 1, 2, 3 ]
        |> List.reverse                    -- [ 3, 2, 1 ]
        |> List.head                       -- Just 3
   else 
      Nothing

もちろん、Maybeを取得します。この関数を使用するときは、それをアンラップする必要があります。リストが空にならない、または不可能なインデックス(1000など)を要求するという保証はありません。そのため、Elmコンパイラーはそのケースを説明するように強制します。

main = 
let 
  fifthElement = 
    case 5 !! [1,2,3,4,255,6] of  // not sure how would you use it in Haskell?! But look's Nice as infix function. (inspired by @Daniël Heres)
      Just a ->
        a
      Nothing ->
        -1
in
    div [] 
        [ text <| toString fifthElement ]         // 255
1
AIon