我有一个数组
input
:
[
{ type: 1, price: 50, discounted_price: 40 },
{ type: 2, price: 150, discounted_price: 140 },
{ type: 1, price: 40, discounted_price: 30 },
{ type: 2, price: 140, discounted_price: 130 }
]
以及预期的输出是什么
[
{
type: 1,
price: 90, # => 50 + 40
discounted_price: 70 # => 40 + 30
},
{
type: 2,
price: 290, # => 150 + 140
discounted_price: 270 # => 140 + 130
}
]
我已经尝试过reduce
和group_by
方法,但无法理解。
https://medium.com/@james.a.hughes/using-the-reduce-method-in-ruby-907f3c18ae1f
input.group_by { |item|
[item[:type]]
}.values.flat_map { |items|
items.first.merge(price: items.sum { |h| h[:price].to_f })
}
它是价格的总和,但是我要价格和折扣价。
答案 0 :(得分:2)
您可以使用group_by
和reduce
:
input.group_by { |item| item[:type] }.map do |_, collection|
collection.reduce do |result, item|
result[:price] += item[:price]
result[:discounted_price] += item[:discounted_price]
result
end
end
但是仅使用reduce
也足够:
input.reduce([]) do |result, item|
result_i = result.find { |result_i| result_i[:type] == item[:type] }
if result_i
result_i[:price] += item[:price]
result_i[:discounted_price] += item[:discounted_price]
result
else
result << item
end
end
答案 1 :(得分:2)
arr = [
{ type: 1, price: 50, discounted_price: 40 },
{ type: 2, price: 150, discounted_price: 140 },
{ type: 1, price: 40, discounted_price: 30 },
{ type: 2, price: 140, discounted_price: 130 }
]
arr.each_with_object({}) do |g,h|
h.update(g[:type]=>g) do |_,o,n|
{ type: o[:type], price: o[:price]+n[:price],
discounted_price: o[:discounted_price] + n[:discounted_price] }
end
end.values
#=> [{:type=>1, :price=>90, :discounted_price=>70},
# {:type=>2, :price=>290, :discounted_price=>270}]
请注意,values
的接收者是
{1=>{:type=>1, :price=> 90, :discounted_price=> 70},
2=>{:type=>2, :price=>290, :discounted_price=>270}}
这使用Hash#update(也称为merge!
)形式,并使用了该块
do |_,o,n|
{ type: o[:type], price: o[:price]+n[:price],
discounted_price: o[:discounted_price] + n[:discounted_price] }
end
确定合并的两个哈希中存在的键的值。有关三个块变量_
,o
和n
的定义,请参见文档。
通常的做法是对未在块计算中使用的任何块变量使用下划线,主要是为了通知读者。在这里,第一个块变量保存公用密钥。 (某些人可能将_k
用于该块变量。)
Hash#update
和Enumerable#group_by在某种意义上紧密相关,因为(如此处)可以使用一个,而另一个可以使用。两者之间的选择通常是一种风格偏好。