2017-01-06 25 views
0

我正在努力更好地理解散列,并且遇到了其中存在重复集合的问题项目,我需要返回这些项目的哈希值,同时添加一个计算这些项目的项。例如...给定项目散列(也是一个散列),返回一个散列,整合重复项并为每个项目提供计数

我有一个杂货项目的散列,每个项目指向另一个散列,描述每个项目的各种属性。

groceries = [ 
    {"avocado" => {:price => 3.0, :on_sale => true}}, 
    {"tomato" => {:price => 1.0, :on_sale => false}}, 
    {"avocado" => {:price => 3.0, :on_sale => true}}, 
    {"kale" => {:price => 5.0, :on_sale => false}} 
] 

而且我希望我的更新杂货是...

groceries_updated = { 
    "avocado" => {:price => 3.0, :on_sale => true, :count => 2}, 
    "tomato" => {:price => 1.0, :on_sale => false, :count => 1}, 
    "kale" => {:price => 5.0, :on_sale => false, :count => 1} 
} 

我最初的做法是首先通过原哈希迭代制作新的哈希所以我有这样的事情。然后,我会再次遍历原始散列,并在我的新散列中增加计数器。 我想知道这是否可以在散列的一次迭代中完成。我也尝试使用#each_with_object方法,但我还需要更好地了解参数。我对#each_with_object的尝试导致添加了:count键的散列数组,但没有合并。

def consolidate_cart(array) 
    array.each do |hash| 
    hash.each_with_object(Hash.new {|h,k| h[k] = {price: nil, clearance: nil, count: 0}}) do |(item, info), obj| 
     puts "#{item} -- #{info}" 
     puts "#{obj[item][:count] += 1}" 
     puts "#{obj}" 
    end 
    end 
end 
+0

这是'inject'的一个经典案例 – meagar

+4

以上代码中的“avocado”是什么?它看起来像一个变量或方法名称(而不是像一个符号或字符串键)。如果是这样,它会返回什么?请记住,一个Hash只能有一个每个键的实例,所以代码'{avocado:“foo”,avocado:“bar”}(其中':avocado'是一个重复的Symbol键) {鳄梨:“酒吧”}'。在解决你陈述的问题之前,你需要重新考虑你的数据结构。 –

+0

“我也尝试过使用'#each_with_object'方法” - 这是谎言。你不能用你提供的输入来尝试任何东西:它不是一个有效的ruby对象。 – mudasobwa

回答

0

您可以使用inject构建综合杂货下列方式:

groceries = [ 
    {"avocado" => {:price => 3.0, :on_sale => true}}, 
    {"tomato" => {:price => 1.0, :on_sale => false}}, 
    {"avocado" => {:price => 3.0, :on_sale => true}}, 
    {"kale" => {:price => 5.0, :on_sale => false}} 
] 

groceries_updated = groceries.inject({}) do |consolidated, grocery| 
    item = grocery.keys.first 
    consolidated[item] ||= grocery[item].merge(count: 0) 
    consolidated[item][:count] += 1 
    consolidated 
end 

inject需要你想建立对象的初始状态(在这种情况下{})和块这将被称为数组的每个元素。该块的目的是修改/填充对象。 关于如何使用inject的一个很好的描述可以找到here

在你的情况下,块会添加一个新项目到一个散列或增加它的count,如果它已经存在。上面的代码将添加一个新项目的散列,其中count为0,仅当它不存在时(这就是||=所做的)。然后它会增加count

有一点要注意的是,原来groceries数组中的值可能不同(例如,一个avocado条目可能有3.0 price,另有3.5的price)。 groceries_updated中的值将包含原始数组中的第一个值。

相关问题