Question

So I have an array built by collect.

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

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

Builds..

=> ["f03", "f04"]

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

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

Builds..

=> ["f01", "f03"]

What I want is to append the collect so that I can build an array from both v03 and v04 so that it looks like this.

=> ["f03", "f04", "f01", "f03"]

And then only keeps unique values so that it looks like this.

=> ["f03", "f04", "f01"]

Take out f03 since it was listed twice.

Was it helpful?

Solution

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

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

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

OTHER TIPS

@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

If you are using rails 3.2

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

In rails 3 I think this should work

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

This is the best way to do this: Relation.where(part: ['v03', 'v04']).uniq.pluck(:car)

Here's a full example:

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"]

Some thoughts:

Don't put asperands in front of your variables unless you want them to be instance variables (e.g. @a should clearly be a -- and even then, a better name would be good. I'd probably get rid of it altogether as shown above).

It is better to use pluck than map, because pluck only selects the relevant data: SELECT car FROM "relations" WHERE "relations"."part" = 'v04' vs SELECT "relations".* FROM "relations" WHERE "relations"."part" = 'v04'

It is better to use .uniq on the ActiveRecord::Relation because it moves the uniqueness into the database rather than trying to do it in memory with Ruby: SELECT DISTINCT car FROM "relations" WHERE "relations"."part" IN ('v03', 'v04')

Why not combine the where calls into one?

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

or possibly

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

The first does more work in Ruby, the second in SQL.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top