2013-07-31 2 views
11

Come posso eliminare alcuni elementi da una matrice e selezionarli?Elimina dalla matrice e restituisce elementi cancellati in Ruby

Ad esempio:

class Foo 
    def initialize 
    @a = [1,2,3,4,5,6,7,8,9] 
    end 

    def get_a 
    return @a 
    end 
end 

foo = Foo.new 
b = foo.get_a.sth{ |e| e < 4 } 
p b # => [1,2,3] 
p foo.get_a # => [4,5,6,7,8,9,10] 

Cosa posso usare al posto di foo.get_a.sth?

+0

La variabile di istanza '@ a' sulla classe' Foo' non sta facendo nulla. Dovresti rimuoverlo. – sawa

+0

La domanda viene astratta e il dettaglio viene rimosso. si può supporre che la riga '@a = [1,2,3,4,5,6,7,8,9]' sia il risultato di un certo processo. – NewMrd

+0

Mi dispiace !! Sono abituato a forma java !!! : p – NewMrd

risposta

22

Se non è necessario per mantenere l'id oggetto di a:

a = [1,2,3,4,5,6,7,8,9,10] 
b, a = a.partition{|e| e < 4} 
b # => [1, 2, 3] 
a # => [4, 5, 6, 7, 8, 9, 10] 

Se si ha bisogno di mantenere l'id oggetto di a, quindi utilizzare una matrice temporale c:

a = [1,2,3,4,5,6,7,8,9,10] 
b, c = a.partition{|e| e < 4} 
a.replace(c) 
+1

bella risposta, ma non posso cambiare il 'a'. 'a' è il risultato di una funzione' some_object.get_some_array' – NewMrd

+0

@NewMrd Perché non è possibile cambiarlo? Una variabile è una variabile, quindi puoi sempre assegnarne una per essere il risultato di quella chiamata, quindi questo modello funziona correttamente. – tadman

+4

Non puoi semplicemente usare 'a.select {| e | e <4} 'in questo caso? Ciò restituirà gli elementi che superano il test. –

0
a = [1, 2, 3, 4] 
a.dup - (a.delete_if(&:even?)) 
#=> [2, 4] 

a 
#=> [1, 3] 

a = [1, 2, 3, 4] 
b = a.dup - (a.delete_if { |e| e < 4 }) 
a 
#=> [4] 
b 
#=> [1, 2, 3] 

Modifica: Sembra che tu sia appena dopo #select ...

a = [1, 2, 3, 4] 
a.select { |e| e < 3 } 
#=> [1, 2] 
+0

Se ci sono elementi duplicati, il blocco restituirà lo stesso per entrambi, quindi questo non è qualcosa che potrebbe essere un problema! –

+0

Puoi fornire un esempio? –

+1

Forse mi sono sbagliato. Scusate. – sawa

1

Se stavate eliminando un solo elemento, questo non richiede duplicare la matrice, ecc:

array = [{ id: 1 }, { id: 2 }, {id: 3 }] 
array.delete_at(array.find_index { |element| element[:id] == 1 }) 
#=> {:id=>1} 
+1

Questa è la soluzione perfetta per la mia applicazione per necessità simili. – Jay

+0

fallirà se find_index restituisce nil – mountriv99

0

Non riesco ancora a credere che ruby ​​non ha qualcosa per questo nelle sue librerie predefinite. Ci dovrebbe essere metodo #drop equivalente per questo. Sicuramente c'è una gemma disponibile che aggiungerebbe la funzionalità alla classe dell'array. Ma chi ha bisogno di gemme quando si può semplicemente uscire i propri script:

#in initializer somewhere 
class Array 
    def exclude(obj) 
    x = self 
    x.delete(obj) 
    x 
    end 
end 

mi può presentare una richiesta di pull al progetto github rubino per questo metodo. Questa patch superman funziona molto bene finora.