7

所以我有一个由collect构建的数组。

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

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

构建..

=> [“f0​​3”,“f04”]

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

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

构建..

=> [“f0​​1”,“f03”]

我想要的是附加收集,以便我可以从 v03 和 v04 构建一个数组,使其看起来像这样。

=> [“f0​​3”,“f04”,“f01”,“f03”]

然后只保留唯一值,使其看起来像这样。

=> [“f0​​3”,“f04”,“f01”]

取出 f03,因为它被列出了两次。

4

4 回答 4

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

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

car1 | car2 #=> ["f03", "f04", "f01"]
于 2012-09-01T19:27:01.853 回答
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

如果您使用的是 Rails 3.2

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

在rails 3中,我认为这应该可行

@relations  = Relation.where(part: parts).collect(&:name).uniq  
于 2012-09-01T19:38:01.363 回答
3

这是执行此操作的最佳方法:Relation.where(part: ['v03', 'v04']).uniq.pluck(:car)

这是一个完整的例子:

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

一些想法:

除非您希望它们成为实例变量,否则不要将连字符放在变量前面(例如@a,显然应该是a- 即便如此,更好的名称也会很好。我可能会完全摆脱它,如上所示)。

使用 pluck 比使用 map 更好,因为 pluck 只选择相关数据:SELECT car FROM "relations" WHERE "relations"."part" = 'v04'vs SELECT "relations".* FROM "relations" WHERE "relations"."part" = 'v04'

最好.uniq在 ActiveRecord::Relation 上使用,因为它将唯一性移动到数据库中,而不是尝试使用 Ruby 在内存中进行:SELECT DISTINCT car FROM "relations" WHERE "relations"."part" IN ('v03', 'v04')

于 2012-09-01T19:58:51.073 回答
2

为什么不将where调用合二为一呢?

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

或者可能

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

第一个在 Ruby 中做更多的工作,第二个在 SQL 中做更多的工作。

于 2012-09-01T19:34:48.837 回答