2011-01-04 13 views

risposta

61
li.delete_at(li.index(n) || li.length) 

li[li.length] è fuori portata, in modo che il || li.length gestisce il caso in cui n non è nella lista.

irb(main):001:0> li = [1,2,3,1,2,3] 
=> [1, 2, 3, 1, 2, 3] 
irb(main):002:0> li.delete_at(li.index(2) || li.length) 
=> 2 
irb(main):003:0> li.delete_at(li.index(42) || li.length) 
=> nil 
irb(main):004:0> li 
=> [1, 3, 1, 2, 3] 
+0

Grazie. Ho battuto la mia testa cercando di esprimere questo elegantemente. –

+0

Non capisco il '|| li.length' chiunque può spiegare per favore – gates

+1

Qualsiasi valore in ruby ​​può essere trattato come valore booleano, con solo 'false' e' nil' che valutano come false. La sintassi del doppio tubo è una comoda abbreviazione. 'a || b' significa "a, a meno che non sia nulla, quindi b". – erich2k8

12

Se || li.length è quello di evitare l'invio di nil a li.delete_at (che si tradurrebbe in un TypeError), quindi una versione più leggibile potrebbe assomigliare a questo

li.delete_at li.index(42) unless li.index(42).nil?

+6

Probabilmente vuoi memorizzare 'li.index (42)' in una variabile, per evitare di fare la ricerca due volte. Le prestazioni saranno molto migliori per i grandi array. – Kelvin

4

Forse dovrebbe diventare parte di stdlib :

class Array 
    def delete_first item 
    delete_at(index(item) || length) 
    end 
end 
Problemi correlati