Return 两个数组根据属性求交后的对象

Return object after performing intersection of two arrays based on attribute

我有两个数组,都填充了具有大量属性的对象。两个数组都包含相同的对象类型。我想根据对象的属性 id

找到对象匹配的位置

对象示例:

#<Link:0x00007fac5eb6afc8 @id = 2002001, @length=40, @area='mars' ...>

填充对象的数组示例:

array_links = [<Link:0x00007fac5eb6afc8>, <Link:0x00007fdf5eb7afc2>, <Link:0x000081dag6zb7agg8>... ]
selected_links = [<Link:0x00007fad8ob6gbh5>, <Link:0x00007fdg7hh4tif4>, <Link:0x000081dag7ij5bhh9>... ]

如果这些是对象 ID 的字符串并且匹配,我可以使用:

intersection = array_links & selected_links

但是我想根据它们的属性和 return 匹配对象本身来执行此操作。 类似于:

intersection = array_links.select(&:id) & selected_links.select(&:id)

但当然不是那样,因为那行不通,有什么想法吗? :)

您可以:

1 :

覆盖 eql?(other) 方法,然后数组交集将起作用

class Link < ApplicationRecord
  def eql?(other)
    self.class == other.class && self.id == other&.id # classes comparing class is a guard here
  end
  
  # you should always update the hash if you are overriding the eql?() 
  def hash
    self.id.hash
  end 
end

2:

使用array.select:

array_links.flat_map {|i| selected_links.select {|k|  k.user_id == i.user_id }}

如果它们在内存中是同一个对象,即array_links = [<Link:0x123]selected_links = [<Link:0x123>],那么你的解决方案是:

intersection = array_links & selected_links

应该可以。

如果不是,您可以遍历 array_linksselect 中的 selected_links:

intersection = array_links.select do |link|
  link.id.in? selected_links.map(&:id)
end 

如果你循环遍历 selected_linksselect 中的那些 array_links,结果将是相同的。

根据您的资源和这些数组的大小,您可以记忆 selected_links.map(&:id) 以防止在每次迭代时重新构建它。