2009-11-25 8 views
14

Per dividere una serie in due parti uguali farei questo,RoR/Rubino eliminare elementi nil da array nidificato

>> a = [1,2,3,4,5] 
=> [1, 2, 3, 4, 5] 
>> a.in_groups_of((a.size/2.0).ceil) if a.size > 0 
=> [[1, 2, 3], [4, 5, nil]] 

ora ho un array nidificato che contiene gli elementi nulli se la dimensione della matrice è strano Come posso rimuovere gli elementi nil dagli array annidati? Voglio fare qualcosa di simile,

a.compact 

Ma purtroppo che non funziona, rubino rimuove solo gli elementi nulli sul primo livello, e non in modo ricorsivo. Ruby fornisce qualche buona soluzione per questo problema?

risposta

44

con Ruby 1.8.7 e successivamente è possibile effettuare le seguenti operazioni:

a.each &:compact! 
=> [[1, 2, 3], [4, 5]] 

Con Ruby 1.8.6, avete fatto questo a lungo:

a.each {|s| s.compact!} 

Entrambe modificheranno il contenuto di a. Se si desidera restituire un nuovo array e lasciare il solo originale, è possibile utilizzare collect invece di each:

# 1.8.7+: 
a.collect &:compact 

# 1.8.6: 
a.collect {|s| s.compact} 
+3

Ho pensato che la sintassi & è stata introdotta in 1.8.7 – EmFi

+1

@EmFi Buon punto - Mi stavo dimenticando 1.8.7. Modificherò la mia risposta. –

+0

Puoi anche usare 'a.map (&: compact)' – Bongs

-3
a.each {|subarray| subarray.compact!} 
a.compact! 

Dovrebbe funzionare ....

+2

Probabilmente non vale la necro-pubblicazione, ma queste due righe dovrebbero essere in ordine inverso. Se assumiamo che 'a' ha' nil's, dovremmo prima * compattarlo *, altrimenti otterremo errori nil all'interno del blocco. – NIA

3

A meno che non si desidera modificare in modo permanente un

a.map do |e| 
    e.compact 
end 
8

Se si sceglie di usare il in_groups_of si può passare false come secondo argomento e non riempirà negli "spazi vuoti" con nil, ma davvero nulla.

0
arr_mixed=['hello', 2222, 'world', nil, [1, 2, 5, 'hi', nil],[1, 2, 3], [4, 5, nil]] 

def compact_nested(array) 
    arr2=[] 
    array.each { |x| 
    element = x.class==Array ? x.compact : x 
    arr2<<element 
    } 
    arr2 
end 

p compact_nested(arr_mixed).compact #=>["hello", 2222, "world", [1, 2, 5, "hi"], [1, 2, 3], [4, 5]] 
p arr_mixed #=>["hello", 2222, "world", nil, [1, 2, 5, "hi", nil], [1, 2, 3], [4, 5, nil]] 
Problemi correlati