2012-09-01 4 views
6

Quindi ho un array creato da collect.Aggiunta di un array di raccolta con valori univoci

@a = Relation.where(part: "v04") 

@relations = @a.collect {|x| x.car} 

Costruisce ..

=> [ "F03", "F04"]

@a = Relation.where(part: "v03") 

@relations = @a.collect {|x| x.car} 

Costruisce ..

=> [ "F01 "," f03 "]

Quello che voglio è aggiungere il raccoglitore in modo che possa costruire un array sia da v03 sia da v04 in modo che assomigli a questo.

=> [ "F03", "F04", "F01", "F03"]

E poi mantiene solo valori unici in modo che assomiglia a questo.

=> [ "F03", "F04", "F01"]

Estrarre f03 da quando è stato elencato due volte.

+0

L'ordine è importante? –

+0

Stai usando Rails presumo? –

risposta

19
["f03", "f04"] | ["f01", "f03"] #=> ["f03", "f04", "f01"] 

car1 = ["f03", "f04"] 
car2 = ["f01", "f03"] 

car1 | car2 #=> ["f03", "f04", "f01"] 
+0

Grazie non si rendeva conto che era così semplice. Che cosa succede se il primo è stato memorizzato nella variabile car1 e nella seconda car2. Come faresti la stessa cosa usando le variabili? –

+0

@TonyHassan, vedere l'aggiornamento – megas

+0

Non importa che l'unione funzioni. Grazie! –

2

Perché non combinare le chiamate where in una?

cars = Relation.where(part: ['v03', 'v04']).map(&:car).uniq 

o eventualmente

car_ids = Relation.where(part: ['v03', 'v04']).select('DISTINCT car_id').map(&:car_id) 
cars = Car.where(id: car_ids) 

Il primo fa più lavoro in rubino, il secondo in SQL.

+0

Grazie questa è un'alternativa solida! –

3
@a = Relation.where(part: "v04") 
@relations1 = @a.collect {|x| x.car} 


@a = Relation.where(part: "v03") 
@relations2 = @a.collect {|x| x.car} 


@all_relations = @relations2 | @relations2 

Se si utilizza rotaie 3.2

parts = ['v03','v04'] 
@relations = Relation.where(part: parts).pluck(:name).uniq 

in Rails 3 Credo che questo dovrebbe funzionare

@relations = Relation.where(part: parts).collect(&:name).uniq 
+0

Grazie mille questo è perfetto! –

+0

@TonyHassan, stai utilizzando le guide o il record attivo? se sì quale versione? – PriteshJ

+0

@TonyHassan controlla la risposta aggiornata se stai utilizzando le guide o la registrazione attiva – PriteshJ

3

Questo è il modo migliore per farlo: Relation.where(part: ['v03', 'v04']).uniq.pluck(:car)

Ecco un esempio completo:

require 'active_record' 

ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:' 

ActiveRecord::Schema.define do 
    self.verbose = false 
    create_table :relations do |t| 
    t.string :part 
    t.string :car 
    end 
end 

Relation = Class.new ActiveRecord::Base 

# build the relations (btw, this name makes no sense) 
Relation.create! car: 'f01', part: 'v03' 
Relation.create! car: 'f03', part: 'v03' 
Relation.create! car: 'f03', part: 'v04' 
Relation.create! car: 'f04', part: 'v04' 

# querying 
Relation.where(part: "v04").pluck(:car) # => ["f03", "f04"] 
Relation.where(part: "v03").pluck(:car) # => ["f01", "f03"] 
Relation.where(part: ['v03', 'v04']).uniq.pluck(:car) # => ["f01", "f03", "f04"] 

Alcuni pensieri:

Non mettere asperands di fronte ai vostri variabili meno che non si desidera che siano variabili di istanza (ad esempio @a dovrebbe essere chiaramente a - e anche allora, un nome migliore sarebbe buono. Probabilmente me ne sbarazzerei del tutto come mostrato sopra).

E 'meglio usare coraggio di carta, perché coraggio seleziona solo i dati rilevanti: SELECT car FROM "relations" WHERE "relations"."part" = 'v04' vs SELECT "relations".* FROM "relations" WHERE "relations"."part" = 'v04'

E' meglio usare .uniq sul ActiveRecord :: Relation perché si muove l'unicità nel database piuttosto che cercare di farlo in memoria con Ruby: SELECT DISTINCT car FROM "relations" WHERE "relations"."part" IN ('v03', 'v04')

+0

Grazie per il vostro consiglio! –