2015-10-09 15 views
6

so di poter dividere un anche lista in due metà uguali in elisir in questo modo:lista divisa in due metà uguali (± 1)

list = [1, 2, 3, 4, 5, 6] 
len = length(list)/2 |> round 

[a, b] = Enum.chunk(list, len)   # => [[1, 2, 3], [4, 5, 6]] 

ma c'è un metodo ruby-esque built-in o un modo più efficiente di fare questo che gestisce anche elenchi di lunghezza dispari?

risposta

8

Enum.chunk prende in realtà 4 argomenti e lavorerà con una lista di lunghezza strano se si include il 4 ° (pad) argomento:

iex(14)> Enum.chunk([1,2,3,4,5], 3, 3, []) 
[[1, 2, 3], [4, 5]] 
2

Non credo che esista un modo "più idiomatico" per farlo. Non conosco un metodo integrato per farlo.

Un suggerimento: se hai a che fare con elenchi più grandi, è meglio usare uno Stream piuttosto che un Enum.

list = [1,2,3,4,5,6,7,8,9] 
s = Stream.take_every(list,2) 
l2 = Enum.to_list(s) #=> [1,3,5,7,9] 

E poi

l1 = list -- l2 #=> [2,4,6,8] 

È meglio usare un flusso in cui è possibile a causa di un flusso è pigramente valutati. In questo caso particolare, non farebbe differenza. Ma in alcuni casi la valutazione pigra può davvero accelerare le cose.

Come ho detto il mio codice non è più idiomatico della soluzione e non è certamente una funzione integrata.

4

Dopo aver consultato i documenti e aver cercato altrove, non ho ancora trovato una soluzione integrata, ma ho trovato Enum.split/2. Questo metodo sembra più adatto per dividere gli elenchi di lunghezza dispari, ma restituisce uno tuple anziché un elenco di elenchi.

Ancora non so quanto sia efficiente.

Esempio:

def split(list) do 
    len = round(length(list)/2) 
    Enum.split(list, len) 
end 


split([1, 2, 3, 4])  # => {[1, 2], [3, 4]} 
split([5, 6, 7, 8, 9])  # => {[5, 6, 7], [8, 9]} 
Problemi correlati