different - add element list erlang
Listas de Erlang: index_of function? (6)
Estoy buscando una función de biblioteca Erlang que devolverá el índice de un elemento en particular en una lista.
Así que si
X=[10,30,50,70]
entonces
lists:index_of(30, X)
devolvería 1, etc., al igual que el método indexOf()
java.util.List
.
¿Existe tal método en la biblioteca estándar de Erlang? Intenté buscar en el módulo de listas pero no tuve suerte. ¿O debería escribirlo yo mismo?
Gracias.
Como han dicho otros, hay maneras más eficientes de resolver esto. Pero si buscas algo rápido, esto funcionó para mí:
string:str(List, [Element]).
Creo que el escritor hace un caso válido. Aquí está mi caso de uso de una aplicación de registro. El objetivo es verificar la gravedad de un error en comparación con las acciones que se realizarán en varios niveles de respuesta de error.
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).
Esta función es muy infrecuente para Erlang y esta puede ser la razón por la que no está en la biblioteca estándar. Ninguno de los programadores de Erlang con experiencia lo necesita y no se recomienda utilizar algoritmos que utilicen esta función. Cuando alguien lo necesita, puede escribir para su propio propósito, pero estas raras ocasiones no son motivo para incluirlo en stdlib
. Diseñe sus estructuras de datos de manera adecuada en lugar de solicitar esta función. En la mayoría de los casos, la necesidad de esta función indica error en el diseño.
La siguiente función devuelve una lista de índices de un elemento dado en una lista. El resultado se puede utilizar para obtener el índice de la primera o última aparición de un elemento duplicado en una lista.
indices_of(Element, L) ->
Indices = lists:zip(lists:seq(1,length(L)), L),
[ I || {I, E} <- Indices, E == Element ].
Otras soluciones (comente que éstas son base-índice = 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.
En algún momento, cuando las listas que pasan a estas funciones se vuelven lo suficientemente largas, la sobrecarga de construir la lista o dictado adicional se vuelve demasiado costosa. Si puede evitar hacer la construcción cada vez que quiera buscar en la lista manteniendo la lista en ese formato fuera de estas funciones, eliminará la mayor parte de los gastos generales.
El uso de un diccionario incluirá los valores de la lista y ayudará a reducir el tiempo de búsqueda del índice a O (registro N), por lo que es mejor usarlo para listas grandes de una sola clave.
En general, depende de usted, el programador, organizar sus datos en estructuras que se adapten a la forma en que los va a utilizar. Mi conjetura es que la ausencia de un index_of incorporado es para alentar tal consideración. Si está haciendo búsquedas de una sola tecla, eso es realmente lo que index_of () es, use un diccionario. Si está realizando búsquedas de varias teclas, use una lista de tuplas con listas: keyfind () et al. Si sus listas son demasiado grandes, una solución menos simplista es probablemente la mejor.
Tendrás que definirlo tú mismo, así:
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).
Sin embargo, tenga en cuenta que acceder al elemento Nth de una lista es O (N), por lo que un algoritmo que a menudo accede a una lista por índice será menos eficiente que uno que itere a través de ella de forma secuencial.