web-dev-qa-db-ja.com

Elmの配列とリスト

ArrayListがElmの2つの異なるタイプであることを知って驚いた。

私の場合、私はList Int長さ2,000,000で、そのうちの約10,000が必要ですが、どれが1万かは事前にわかりません。それは別のリストによって提供されます。擬似コードの場合:

x = [ 1,1,0,30,...,255,0,1 ]
y = [ 1,4,7,18,36,..., 1334823 , ... 1899876 ]
z = [ y[x[0]], y[x[1]], ... ]

明らかにこれはElm構文ではないため(正当なJavaScriptである可能性があります)、擬似コードを使用しています。

これらの配列の選択は、ListまたはArray、あるいはその両方で行うことができますか?

19
john mangual

Listは、インデックスに基づくO(n)ルックアップ時間を提供するリンクリストです。インデックスごとに要素を取得するには、nノード上でリストをトラバースする必要があります。 Listのインデックスルックアップ関数はコアライブラリでは使用できませんが、ルックアップ用の2つの関数を提供する Elm-community/list-extra パッケージを使用できます(パラメーターの順序によって異なります) : !! および getAt

Arrayは、O(log n)インデックスルックアップを可能にします。 Arrayのインデックス検索は、 Array.get を使用して実行できます。配列は Relaxed Radix Balanced Trees として表されます。

どちらも不変であるため(Elmのすべての値は不変です)、状況に応じてトレードオフがあります。 Listは、リンクリストポインタを更新するだけなので、多くの変更を加える場合に最適です。一方、Arrayは、迅速な検索には最適ですが、変更のパフォーマンスはやや劣ります。多くの変更を加えているかどうかを検討してください。

37
Chad Gilbert

このようなものが機能するはずです:

import Array
import Debug

fromJust : Maybe a -> a
fromJust x = case x of
    Just y -> y
    Nothing -> Debug.crash "error: fromJust Nothing"

selectFromList : List a -> List Int -> List a
selectFromList els idxs = 
  let arr = Array.fromList els
   in List.map (\i -> fromJust (Array.get i arr)) idxs

入力リストを配列に変換して高速インデックスを作成し、インデックスのリストを配列内の対応する値にマップします。 このStackOverflowの質問 からfromJust関数を取得しました。

1
Alex Reinking