给定项目的哈希值(也是哈希值),返回一个哈希值,用于合并重复项并为每个项目提供计数

问题描述 投票:0回答:2

我正在努力更好地理解哈希,并且我遇到了一些问题,其中我有一个带有重复项目的集合,我需要返回这些项目的哈希值,同时添加一个计算这些项目的密钥。例如...

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

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 
ruby hash count hash-of-hashes
2个回答
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,另一个price为3.5)。 groceries_updated中的值将包含原始数组中的第一个值。


0
投票

单行(几乎只是在一些链式块中分开):

groceries.
  group_by { |h| h.keys.first }.
  transform_values { |v| v.first.values.first.merge(count: v.size) }

说明:

第一个块根据(假设的单个)哈希键将列表拆分为多个值:

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

第二个块占用一个值

[
  {"avocado" => {:price => 3.0, :on_sale => true}},
  {"avocado" => {:price => 3.0, :on_sale => true}}
]

读取第一个项目的所谓单个值,并与总计数合并。

:那么:

© www.soinside.com 2019 - 2024. All rights reserved.