リスト内の特定の要素のインデックスを返すErlangライブラリ関数を探しています。
だから、もし
X = [10,30,50,70]
lists:index_of(30, X)
java.util.List
のindexOf()
メソッドと同じように、1などを返します。
そのようなメソッドはErlang標準ライブラリに存在しますか?リストモジュールを調べてみましたが、うまくいきませんでした。それとも私はそれを自分で書くべきですか?
リスト内の特定の要素のインデックスを返すErlangライブラリ関数を探しています。
だから、もし
X = [10,30,50,70]
lists:index_of(30, X)
java.util.List
のindexOf()
メソッドと同じように、1などを返します。
そのようなメソッドはErlang標準ライブラリに存在しますか?リストモジュールを調べてみましたが、うまくいきませんでした。それとも私はそれを自分で書くべきですか?
次のように、自分で定義する必要があります。
index_of(Item, List) -> index_of(Item, List, 1).
index_of(_, [], _) -> not_found;
index_of(Item, [Item|_], Index) -> Index;
index_of(Item, [_|Tl], Index) -> index_of(Item, Tl, Index+1).
ただし、リストのN番目の要素にアクセスするのはO(N)であるため、インデックスによってリストにアクセスすることが多いアルゴリズムは、リストを順番に繰り返すアルゴリズムよりも効率が悪いことに注意してください。
他の人が指摘したように、これを解決するためのより効率的な方法があります。しかし、何か手っ取り早いものを探しているなら、これは私にとってはうまくいきました:
string:str(List, [Element]).
その他の解決策 (これらは base-index=1 であることに注意してください):
index_of(Value, List) ->
Map = lists:zip(List, lists:seq(1, length(List))),
case lists:keyfind(Value, 1, Map) of
{Value, Index} -> Index;
false -> notfound
end.
index_of(Value, List) ->
Map = lists:zip(List, lists:seq(1, length(List))),
case dict:find(Value, dict:from_list(Map)) of
{ok, Index} -> Index;
error -> notfound
end.
ある時点で、これらの関数に渡すリストが十分に長くなると、追加のリストまたは dict を作成するオーバーヘッドが高くなりすぎます。これらの関数の外でリストをその形式のままにしておくことで、リストを検索するたびに構築を行うことを避けることができれば、ほとんどのオーバーヘッドを排除できます。
ディクショナリを使用すると、リスト内の値がハッシュされ、インデックスのルックアップ時間が O(log N) に短縮されるため、単一キーの大きなリストにはディクショナリを使用することをお勧めします。
一般に、データをどのように使用するかに適した構造にデータを編成するのは、プログラマであるあなた次第です。私の推測では、組み込みの index_of がないことは、そのような考慮を促すためのものです。単一キーのルックアップを行っている場合 (実際には index_of() がそうです)、辞書を使用します。複数キーのルックアップを行っている場合は、lists:keyfind() などでタプルのリストを使用します。リストが非常に大きい場合は、単純化されていないソリューションがおそらく最適です。
この関数はErlangでは非常にまれであり、これが標準ライブラリにない理由である可能性があります。経験豊富なErlangプログラマーは誰もそれを必要とせず、この関数を使用するアルゴリズムを使用することをお勧めしません。誰かがそれを必要とするとき、自分の目的のために書くことができますが、この非常にまれな機会はそれをに含める理由ではありませんstdlib
。この関数を要求するのではなく、適切な方法でデータ構造を設計します。ほとんどの場合、この機能の必要性は設計の誤りを示しています。
次の関数は、リスト内の特定の要素のインデックスのリストを返します。Result を使用して、リスト内の重複要素の最初または最後の出現のインデックスを取得できます。
indices_of(Element, L) ->
Indices = lists:zip(lists:seq(1,length(L)), L),
[ I || {I, E} <- Indices, E == Element ].
筆者は正当な主張をしていると思います。これは、ロギング アプリケーションからの私のユース ケースです。目的は、さまざまなレベルのエラー応答に対して実行されるアクションに対して、エラーの重大度をチェックすることです。
get_index(A,L) ->
get_index(A,L,1).
get_index(A,[A|_],N) ->
N;
get_index(A,[_|T],N) ->
get_index(A,T,N+1).
get_severity(A) ->
Severity=[debug,info,warn,error],
get_index(A,Severity).