Erlang列表:index_of/2函数?

ljo96ir5  于 2022-12-08  发布在  Erlang
关注(0)|答案(6)|浏览(177)

我正在寻找一个Erlang库函数,它将返回列表中特定元素的索引。
所以,如果
第一个
将返回1等,就像java.util.ListindexOf()方法一样。
Erlang标准库中是否存在这样的方法?我试着在列表模块中查找,但没有找到。或者我应该自己编写它吗?

piok6c0g

piok6c0g1#

您必须自己定义它,如下所示:

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)的,所以经常通过索引访问列表的算法将比顺序地迭代通过它的算法效率低。

tkclm6bt

tkclm6bt2#

正如其他人所指出的,有更有效的方法来解决这个问题。但如果你想快速解决问题,这对我很有效:

string:str(List, [Element]).
sf6xfgos

sf6xfgos3#

Other solutions (remark that these are 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.

At some point, when the lists you pass to these functions get long enough, the overhead of constructing the additional list or dict becomes too expensive. If you can avoid doing the construction every time you want to search the list by keeping the list in that format outside of these functions, you eliminate most of the overhead.
Using a dictionary will hash the values in the list and help reduce the index lookup time to O(log N), so it's better to use that for large, singly-keyed lists.
In general, it's up to you, the programmer, to organize your data into structures that suit how you're going to use them. My guess is that the absence of a built-in index_of is to encourage such consideration. If you're doing single-key lookups -- that's really what index_of() is -- use a dictionary. If you're doing multi-key lookups, use a list of tuples with lists:keyfind() et al. If your lists are inordinately large, a less simplistic solution is probably best.

ckocjqey

ckocjqey4#

这个函数对于Erlang来说是非常少见的,这可能是它没有在标准库中的原因。没有一个有经验的Erlang程序员需要它,并且不鼓励使用使用这个函数的算法。当有人需要它的时候,我可以为自己的目的写,但这种非常罕见的情况不是把它包含到stdlib中的理由。用正确的方式设计你的数据结构,而不是要求这个函数。在大多数情况下,需要此功能表示设计错误。

j8ag8udp

j8ag8udp5#

我认为作者提出了一个有效的案例。下面是我从一个日志应用程序中得到的用例。目标是根据不同级别的错误响应执行的操作来检查错误的严重性。

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).
yyhrrdl8

yyhrrdl86#

下面的函数返回列表中给定元素的索引列表。结果可用于获取列表中第一个或最后一个重复元素的索引。

indices_of(Element, L) ->                                                                                                                                                          
    Indices = lists:zip(lists:seq(1,length(L)), L),                                                                                                                                
    [ I || {I, E} <- Indices, E == Element ].

相关问题