缩短映射和连接

Shorten mapping and concat

我得到一个包含 person 个对象的数组。一个person可以有多个houses:

 person.houses => ActiveRecord_Associations_CollectionProxy

有些房子可以属于几个persons。在我的代码中,我想为数组中的人获取所有唯一的 houses

这是代码的长版:

 def persons_houses(persons)
   unique_houses = []

   persons.each do |person|
     person.houses.each do |house|
        unique_houses << house if !unique_houses.include? house
     end
   end

   unique_houses
 end

你知道这个 persons_houses(persons) 方法的更短代码吗?

我正在考虑绘制人物房屋的地图,同时连接它们,然后 return 唯一值

类似于:(但这是无效的Ruby)

persons.map { |person| concat(person.houses) }.uniq

感谢您的帮助!

每个人有很多房子,一个房子可能属于很多人?怎么样:

persons.map(&:houses).flatten.uniq

您可以使用单个数据库查询来执行此操作,而无需创建要解析的数组。假设你有一个关系 table(不知道一个人可以有很多房子,一个房子可以有很多人),并假设你的关系 table 被称为 ownerships,你会做:

House.joins(:ownerships).where(ownerships: {person_id: persons.ids}).uniq

这比建议的其他答案要快得多,内存效率也高得多,而且它还给您留下了 ActiveRecord_Relation,因此您可以进一步确定结果范围。