2009-03-02 12 views
29

Ho bisogno di una collezione che sia come un set. Fondamentalmente sto scannerizzando una lunga stringa e aggiungendo parole alla collezione, ma voglio essere in grado di rilevare quando ci sono duplicati.Imposta in Ruby?

Se i set non sono disponibili, qual è il modo più efficiente per farlo in Ruby? Punti Brownie per esempio il codice.

risposta

16

Dal documentation:

a = [ "a", "a", "b", "b", "c" ] 
a.uniq #gets you ["a", "b", "c"] 
a.uniq.uniq! #gets you nil (no duplicates :) 
+0

C'è qualcosa di simile che mi dice che ci sono duplicati nell'array? O uniq ha qualche valore di ritorno? – alamodey

+3

uniq: restituisce un nuovo array rimuovendo i valori duplicati in self. uniq !: rimuove gli elementi duplicati da se stessi. Restituisce nullo se non vengono apportate modifiche (ovvero, non vengono trovati duplicati). – dirkgently

5

Dai un'occhiata a questo url /core/classes/Set.html sopra a ruby-doc.org

+0

Il link non funziona più. È stato rimosso dall'API di base? – Florin

+0

Link aggiornato ... –

60

c'è una classe Set in Ruby. Si può usare in questo modo:

require 'set' 

set = Set.new 

string = "a very very long string" 

string.scan(/\w+/).each do |word| 
    unless set.add?(word) 
    # logic here for the duplicates 
    end 
end 

Anche se, mi chiedo se si vuole contare le istanze in tal caso il seguente esempio potrebbe essere migliore:

instances = Hash.new { |h, k| h[k] = 0 } 

string.scan(/\w+/).each do |word| 
    instances[word] += 1 
end 
+1

Su Ruby 1.9 e versioni successive non è necessario 'richiedere' set'' più, è già lì. Inoltre, quando esegui 'my_set.concat [1,2,3]' le cose che aggiungi al set verranno lanciate su un altro 'Set' – Julik

+1

@ Julik, devi ancora assolutamente 'richiedere' set''. – ndn