Erlang列出:index_of函数?

Jus*_*tin 18 erlang

我正在寻找一个Erlang库函数,它将返回列表中特定元素的索引.

因此,如果

X=[10,30,50,70]
Run Code Online (Sandbox Code Playgroud)

然后

lists:index_of(30, X)
Run Code Online (Sandbox Code Playgroud)

将返回1,等等,就像java.util.ListindexOf()方法.

Erlang标准库中是否存在这样的方法?我试着查看列表模块,但没有运气.或者我应该自己写吗?

谢谢.

sep*_*p2k 21

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

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).
Run Code Online (Sandbox Code Playgroud)

但是请注意,访问列表的第N个元素是O(N),因此通常按索引访问列表的算法效率低于按顺序迭代列表的算法.

  • 返回像'not_found`而不是`-1`这样的原子会更像Erlang.这样,如果您忘记测试此情况,则会出现快速错误. (4认同)
  • 索引也可以从 1 而不是 0 开始。 (2认同)
  • ...因为列表:第n个(索引,列表)将1视为第一个项目. (2认同)

Wil*_*ion 15

正如其他人所指出的,有更有效的方法来解决这个问题.但如果你正在寻找快速的东西,这对我有用:

string:str(List, [Element]).
Run Code Online (Sandbox Code Playgroud)


小智 5

其他解决方案(请注意这些是 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.
Run Code Online (Sandbox Code Playgroud)

在某些时候,当您传递给这些函数的列表变得足够长时,构建附加列表或字典的开销就会变得过于昂贵。如果您可以通过在这些函数之外保留该格式的列表来避免每次要搜索列表时都进行构造,则可以消除大部分开销。

使用字典将散列列表中的值并有助于将索引查找时间减少到 O(log N),因此最好将其用于大型单键列表。

一般而言,由您作为程序员来组织您的数据到适合您将如何使用它们的结构中。我的猜测是,没有内置 index_of 是为了鼓励这种考虑。如果你在做单键查找——这就是 index_of() 的真正含义——使用字典。如果您要进行多键查找,请使用带有列表的元组列表:keyfind() 等。如果您的列表非常大,那么不那么简单的解决方案可能是最好的。