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_links
和 select
中的 selected_links
:
intersection = array_links.select do |link|
link.id.in? selected_links.map(&:id)
end
如果你循环遍历 selected_links
和 select
中的那些 array_links
,结果将是相同的。
根据您的资源和这些数组的大小,您可以记忆 selected_links.map(&:id)
以防止在每次迭代时重新构建它。
我有两个数组,都填充了具有大量属性的对象。两个数组都包含相同的对象类型。我想根据对象的属性 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_links
和 select
中的 selected_links
:
intersection = array_links.select do |link|
link.id.in? selected_links.map(&:id)
end
如果你循环遍历 selected_links
和 select
中的那些 array_links
,结果将是相同的。
根据您的资源和这些数组的大小,您可以记忆 selected_links.map(&:id)
以防止在每次迭代时重新构建它。