We have an array of Link objects
links
=>
[#<Link:0x00000001130ba5b8
id: 197,
component_id: 191,
quantity: 0.3>,
#<Link:0x0000000113098648
id: 198,
component_id: 191,
quantity: 0.4>,
#<Link:0x0000000113073fa0
id: 201,
component_id: 193,
quantity: 0.3>,
#<Link:0x0000000113073e10
id: 202,
component_id: 194,
quantity: 0.3>,
#<Link:0x00000001130234d8
id: 209,
component_id: 194,
quantity: 0.8>,
#<Link:0x00000001130385b8
id: 208,
component_id: 199,
quantity: 0.6>]
We need to get an array with unique component_id's and have the quantity added up. I tried
links.uniq { |x| x.component_id }
=>
[#<Link:0x00000001130ba5b8
id: 197,
component_id: 191,
quantity: 0.3>,
#<Link:0x0000000113073fa0
id: 201,
component_id: 193,
quantity: 0.3>,
#<Link:0x0000000113073e10
id: 202,
component_id: 194,
quantity: 0.3>,
#<Link:0x00000001130385b8
id: 208,
component_id: 199,
quantity: 0.6>]
Which works but I'm not sure how to get quantity added up in the new unique array so we get the following
[#<Link:0x00000001130ba5b8
id: 197,
component_id: 191,
quantity: 0.7>,
#<Link:0x0000000113073fa0
id: 201,
component_id: 193,
quantity: 0.3>,
#<Link:0x0000000113073e10
id: 202,
component_id: 194,
quantity: 1.1>,
#<Link:0x00000001130385b8
id: 208,
component_id: 199,
quantity: 0.6>]
If someone could point me in the right direction that would be greatly appreciated. The following works but seems very inefficient
unique = links.uniq { |x| x.component_id }
diff = links - unique
diff.each do |link|
x = unique.select { |e| e.component_id == link.component_id }
x.first.quantity = link.quantity
end
puts unique
CodePudding user response:
Here's my take on this, with group_by and transform_values:
new_links = links.group_by(&:component_id)
.transform_values do |values|
dup = values[0].dup
dup.quantity = values.sum(&:quantity)
dup
end.values
pp new_links
The replit !
CodePudding user response:
Input
I changed your input a bit to make a meaningful data structure.
links = [{ Link: 0x00000001130ba5b8,
id: 197,
component_id: 191,
quantity: 0.3 },
{ Link: 0x0000000113098648,
id: 198,
component_id: 191,
quantity: 0.4 },
{ Link: 0x0000000113073fa0,
id: 201,
component_id: 193,
quantity: 0.3 },
{ Link: 0x0000000113073e10,
id: 202,
component_id: 194,
quantity: 0.3 },
{ Link: 0x00000001130234d8,
id: 209,
component_id: 194,
quantity: 0.8 },
{ Link: 0x00000001130385b8,
id: 208,
component_id: 199,
quantity: 0.6 }]
Code
result = links.group_by { |x| x[:component_id] }
.values
.map do |arr|
arr.reduce do |h1, h2|
h1.merge(h2) do |k, v1, v2|
k.eql?(:quantity) ? v1 v2 : v1
end
end
end
p result
Output
[{:Link=>4614497720, :id=>197, :component_id=>191, :quantity=>0.7}, {:Link=>4614209440, :id=>201, :component_id=>193, :quantity=>0.3}, {:Link=>4614209040, :id=>202, :component_id=>194, :quantity=>1.1}, {:Link=>4613965240, :id=>208, :component_id=>199, :quantity=>0.6}]