Listes Erlang: index des fonctions?

je cherche une fonction de bibliothèque Erlang qui renverra l'index d'un élément particulier dans une liste.

Donc, si

X=[10,30,50,70]

lists:index_of(30, X)

retour 1, etc., tout comme java.util.ListindexOf() méthode.

Existe-t-il une telle méthode dans la norme Erlang lib? J'ai essayé de regarder dans le module des listes mais pas de chance. Ou dois-je l'écrire moi-même?

Merci.

18
demandé sur Svante 2009-09-22 13:56:40

6 réponses

Vous devez définir vous-même, comme ceci:

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

notez cependant que l'accès au nième élément d'une liste est O(N), de sorte qu'un algorithme qui accède souvent à une liste par index sera moins efficace qu'un algorithme qui itère par itération séquentielle.

21
répondu sepp2k 2009-09-22 17:47:36

comme d'autres l'ont fait remarquer, il existe des moyens plus efficaces de résoudre ce problème. Mais si vous cherchez quelque chose de rapide, cela a fonctionné pour moi:

string:str(List, [Element]).
14
répondu William Luxion 2011-07-20 12:50:55

autres solutions (notez qu'il s'agit de 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.

à un moment donné, lorsque les listes que vous passez à ces fonctions sont assez longues, le coût de construction de la liste supplémentaire ou dict devient trop cher. Si vous pouvez éviter de faire la construction chaque fois que vous voulez rechercher la liste en gardant la liste dans ce format en dehors de ces fonctions, vous éliminez la plupart de la charge.

L'utilisation d'un dictionnaire hachera les valeurs dans la liste et aide à réduire le temps de recherche de l'index à o(log N), de sorte qu'il est préférable de l'utiliser pour les grandes listes à une seule touche.

En général, c'est à vous, le programmeur, pour organiser vos données dans des structures adaptées à la façon dont vous allez utiliser. Je pense que l'absence d'un index_of intégré est de favoriser une telle considération. Si vous faites des recherches à une seule touche -- c'est en fait ce qu'est index_of () -- utilisez un dictionnaire. Si vous faites des recherches multi-clés, utilisez une liste de tuples avec listes: keyfind () et al. Si vos listes sont trop volumineuses, une solution moins simpliste est probablement préférable.

3
répondu user502652 2017-11-16 08:58:19

Cette fonction est très rare pour Erlang et c'est peut-être la raison pourquoi il n'est pas dans la bibliothèque standard. Aucun programmeur expérimenté D'Erlang n'en a besoin et n'est pas encouragé à utiliser des algorithmes utilisant cette fonction. Quand quelqu'un en a besoin, il peut écrire dans son propre but, mais ce n'est pas une raison pour l'inclure dans stdlib. Concevez vos structures de données de manière appropriée au lieu de demander cette fonction. Dans la plupart des cas, le besoin de cette fonction indique une erreur de conception.

1
répondu Hynek -Pichi- Vychodil 2009-09-22 18:44:27

je pense que l'auteur fait un cas valable. Voici mon dossier d'utilisation d'une application de journalisation. L'objectif est de vérifier la gravité d'une erreur sur les mesures à prendre contre les différents niveaux de réponse d'erreur.

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).
-1
répondu tony wallace 2012-11-11 08:59:12

La fonction suivante renvoie une liste d'indices d'un élément donné dans une liste. Résultat peut être utilisé pour obtenir l'index de la première ou dernière occurrence d'un élément dupliqué dans une liste.

indices_of(Element, L) ->                                                                                                                                                          
    Indices = lists:zip(lists:seq(1,length(L)), L),                                                                                                                                
    [ I || {I, E} <- Indices, E == Element ].   
-1
répondu savas 2017-02-25 20:40:15