2011-10-22 15 views
23

Ho la seguente matrice:Rails: Rimuovere elemento da array di hash

array = [{"email"=>"[email protected]", "name"=>"Test"}, 
      {"email"=>"[email protected]", "name"=>"Test A"}, 
      {"name"=>"Test B", "email"=>"[email protected]"}, 
      {"email"=>"[email protected]", "name"=>"Test C"}, 
      {"name"=>"Test D", "email"=>"[email protected]"}, 
      {"email"=>"[email protected]"}, 
      {"name"=>"Test F", "email"=>"[email protected]"}] 

Ho una lista di "lista nera" messaggi di posta elettronica, per esempio:

blacklist = ["[email protected]"] 

voglio fare qualcosa di simile questo:

array - blacklist 
# => should remove element {"email"=>"[email protected]", "name"=>"Test C"} 

Sicuramente c'è un modo sexy-Ruby per fare questo con .select o qualcosa del genere, ma non sono stati in grado di capirlo. Ho provato questo senza alcun risultato:

array.select {|k,v| v != "[email protected]"} # => returns array without any changes 

risposta

51

Penso che siete in cerca di questo:

filtered_array = array.reject { |h| blacklist.include? h['email'] } 

o se si desidera utilizzare select invece di reject (forse non si vuole fare del male a chiunque sia sentimenti):

filtered_array = array.select { |h| !blacklist.include? h['email'] } 

tuo

array.select {|k,v| ... 

tentativo non funzionerà perché la matrice passa il blocco Enumerable di un singolo elemento e quell'elemento sarà un hash in questo caso, il trucco |k,v| funzionerebbe se array avesse due array di elementi come elementi.

+0

brillante! grazie per il rapido turnaround :) infatti, hai risposto così velocemente che non riesco nemmeno ad "accettare" la risposta sul sistema SO. – MorningHacker

+1

c'è anche una funzione di esclusione che è e alias per! Include –

+0

@Darren: L'unico svantaggio è che ['escludi?'] (Http://api.rubyonrails.org/classes/Enumerable.html#method-i- exclude-3F) è un'estensione di Rails che porterebbe in doppio territorio negativo :) Probabilmente andrei con il 'reject' /' include? '. –

2

Come su

array.delete_if {|key, value| value == "[email protected]" } 
+4

simile a @mu è troppo breve 'select', dovrebbe essere' array.delete_if {| hash | hash ["email"] == "[email protected]"} ' – PeterWong

+0

delete_if funziona in posizione (di solito non è una buona idea), l'OP sembra voler un nuovo array. – tokland

Problemi correlati