2015-09-29 8 views
23
{status, body} = File.read("/etc/hosts") 
if status == :ok do 
    hosts = String.split body, "\n" 
    hosts = Enum.map(hosts, fn(host) -> line_to_host(host) end) 
else 
    IO.puts "error reading: /etc/hosts" 
end 

Ho la seguente funzione di elisir dove ho letto il file/etc/hosts e cercare di dividerlo riga per riga usando String.split.Come ottenere gli elementi della lista in base all'indice in elisir

Quindi eseguo la mappatura dell'elenco di linee degli host e di chiamare line_to_host (host) per ciascuno. Il metodo line_to_host divide la linea da " " e poi voglio impostare il from e to variabile:

def line_to_host(line) do 
    data = String.split line, " " 
    from = elem(data, 0) // doesn't work 
    to = elem(data, 1) // doesn't work either 
    %Host{from: from, to: to} 
end 

ho guardato attraverso StackOverflow, la documentazione elisir e Googled su come ottenere un elemento di lista in un indice specifico. So che c'è head/tail ma ci deve essere un modo migliore per ottenere gli elementi della lista.

elem(list, index) fa esattamente ciò di cui ho bisogno ma sfortunatamente non funziona con String.split.

Come ottenere elementi di lista/tuple per ID in elisir

+0

don t vuole fare '{status, corpo} = File.read ("/ etc/hosts") 'seguito da' if'. Preferisci il pattern matching: 'case File.read ("/etc/hosts ") do {: ok, body} -> ...' –

+0

ok, bello saperlo. grazie compagno. –

risposta

24

È possibile utilizzare pattern matching per questo:

[from, to] = String.split line, " " 

Forse si desidera aggiungere parts: 2 opzione per garantire otterrete solo due parti in caso non v'è più di uno spazio nella linea:

[from, to] = String.split line, " ", parts: 2 

c'è anche Enum.at/2, che avrebbe funzionato bene qui, ma è unidiomatic. Il problema con Enum.at è che a causa dell'implementazione dell'elenco in Elixir, è necessario attraversare l'intero elenco fino all'indice richiesto in modo che possa essere molto inefficiente per elenchi di grandi dimensioni.


Edit: ecco l'esempio richiesto con Enum.at, ma io non lo uso in questo caso

parts = String.split line, " " 
from = Enum.at(parts, 0) 
to = Enum.at(parts, 1) 
+0

Sono un po 'insoddisfatto da questa soluzione. Non è possibile ottenere solo la parte X di tali ritorni String.split? Enum.at non ha funzionato con String.split. –

+1

Enum.at dovrebbe funzionare bene. Aggiungerò un esempio alla mia risposta. Tenete a mente, è molto unidiomatico usare Enum.at in Elisir, se può essere risolto diversamente. –

+0

Come rendere 'Enum.map' dal secondo elemento nell'array (ad esempio saltando il primo)? –

Problemi correlati