假设我们有一个包含需要提取的对象ID的数组
这是需要从另一个对象数组
获取的ID`idvalues=[2,3]`
这是对象数组
array_object=[#<CustomPricing id: 2, base_price: 500>, #<CustomPricing id: 3, base_price: 700>, #<CustomPricing id: 4, base_price: 900>, #<CustomPricing id: 2, base_price: 500>]
我们如何使用id's
2
&amp; 3
并将它们放入新数组中。这里也有多个具有相同id的记录,所以只想要第一条记录。
我试过这个
events = idvalues.each {|id_value| array_object.find(id=id_value)}
但这会返回idvalue
本身[2,3]
。我们怎样才能做到这一点?
答案 0 :(得分:3)
一种解决方案是:
grouped = array_object.group_by(&:id)
selected = idvalues.uniq.map { |id| grouped[id].first }
(如果idvalues数组不包含任何重复项,则可以删除uniq)
或其他版本
selected = array_object.group_by(&:id).values_at(*id_values).map(&:first)
(见@mudasobwa对此答案的评论)
首先按id
对价格进行分组,然后使用map
查找ID与具有该ID的第一个定价的映射。
但@mudasobwa对你的问题的评论显示了一种更简单的方法来解决这个问题:
selected = idvalues.map {|id| array_object.find { |o| o.id == id} }
剩下的问题:为什么array_object
甚至包含重复的价格?
如果它们是唯一的,您可以使用select:
selected = array_object.select { |pricing| idvalues.includes?(pricing.id) }
您可以先将数组设为uniq:
selected = array_object.select { |pricing| idvalues.includes?(pricing.id) }
(如果数组中的对象实现了正确的相等运算符)
但老实说,我认为数组首先不应包含重复的项目。这听起来像一个可以优化的查询?
答案 1 :(得分:1)
这是一种从array_object
中提取所需实例的方法,该方法旨在提高效率。
<强>代码强>
require 'set'
def extract(array_object, id_values)
idv = id_values.to_set
arr = []
array_object.each do |obj|
id = obj[:id]
if idv.include?(id)
arr << obj
idv.delete(id)
end
break if idv.empty?
end
idv.empty? ? arr : nil
end
示例强>
id_values = [2, 3]
CustomPricing = Struct.new(:id, :base_price) {}
array_object = [[3, 700], [2, 500], [4, 900], [2, 500]].map do |id, bp|
CustomPricing.new(id, bp)
end
#=> [#<struct CustomPricing id=3, base_price=700>,
# #<struct CustomPricing id=2, base_price=500>,
# #<struct CustomPricing id=4, base_price=900>,
# #<struct CustomPricing id=2, base_price=500>]
不熟悉结构(或需要刷新)的读者可能希望阅读this article。
extract(array_object, id_values)
#=> [#<struct CustomPricing id=3, base_price=700>,
# #<struct CustomPricing id=2, base_price=500>]
如果要按照:id
的值id_values
排序对象,则倒数第二行(idv.empty? ? arr : nil
)可以替换为以下内容。
idv.empty? ? arr.sort_by { |obj| id_values.index(obj[:id]) } : nil
产生以下返回值。
[#<struct CustomPricing id=2, base_price=500>,
#<struct CustomPricing id=3, base_price=700>]