在Ruby中按值分组哈希

20

我在 Ruby 中有一个哈希(hash),看起来像这样:

{
  "admin_milestones"=>"1",
  "users_milestones"=>"0",
  "admin_goals"=>"1",
  "users_goals"=>"0", 
  "admin_tasks"=>"1", 
  "users_tasks"=>"0",
  "admin_messages"=>"1",
  "users_messages"=>"0",
  "admin_meetings"=>"1",
  "users_meetings"=>"0"
}

我正在寻找一种解决方案,可以将这个哈希值分成两部分,一部分的值为1,另一个哈希值的值为0。


我特别在寻找用户下面回答的内容,谢谢。 - 123
5个回答

41
您可以按其值对哈希进行分组:
h1 = {
  "admin_milestones"=>"1",
  "users_milestones"=>"0",
  "admin_goals"=>"1",
  "users_goals"=>"0", 
  "admin_tasks"=>"1", 
  "users_tasks"=>"0",
  "admin_messages"=>"1",
  "users_messages"=>"0",
  "admin_meetings"=>"1",
  "users_meetings"=>"0"
}

h2 = h1.group_by{|k,v| v}

它将会按其值分组产生一个哈希,就像这样:
h2 = {"1"=>[["admin_milestones", "1"], ["admin_goals", "1"], ["admin_tasks", "1"], ["admin_messages", "1"], ["admin_meetings", "1"]], 
"0"=>[["users_milestones", "0"], ["users_goals", "0"], ["users_tasks", "0"], ["users_messages", "0"], ["users_meetings", "0"]]} 

7
如果您想要一个数组作为答案,最干净的解决方法是使用分区方法。
zeros, ones = my_hash.partition{|key, val| val == '0'}

1
这个是更好的解决方案。 - 123
1
注意:分区仅适用于将数据分为两个桶(真和假)的布尔分离。如果您想要将数据分成多个类别,则无法使用它。 - Christopher Oezbek
{a: '0', b: '1', c: '2'}.partition {|key, val| val == '0'}

返回的结果是[[[:a, "0"]], [[:b, "1"], [:c, "2"]]]

我希望得到的数组应该是一个哈希数组。
- user2453676

5

你应该在 keys 数组上使用 group_by,并将值用作分组元素:

h1 = {
  "admin_milestones"=>"1",
  "users_milestones"=>"0",
  "admin_goals"=>"1",
  "users_goals"=>"0", 
  "admin_tasks"=>"1", 
  "users_tasks"=>"0",
  "admin_messages"=>"1",
  "users_messages"=>"0",
  "admin_meetings"=>"1",
  "users_meetings"=>"0"
}

# group_by on the keys, then use the value from the hash as bucket
h2 = h1.keys.group_by { |k| h1[k] }

puts h2.inspect

返回一个从值到键数组的哈希表:
{
    "1" => [
        [0] "admin_milestones",
        [1] "admin_goals",
        [2] "admin_tasks",
        [3] "admin_messages",
        [4] "admin_meetings"
    ],
    "0" => [
        [0] "users_milestones",
        [1] "users_goals",
        [2] "users_tasks",
        [3] "users_messages",
        [4] "users_meetings"
    ]
}

不错! 通过块的结果对集合进行分组。返回一个哈希表,其中键是从块中评估的结果,值是与键对应的集合中的元素数组。 - Sandip Subedi

3

仅使用 Hash.select

h1.select { |key, value| value == '0' } #=> {"users_milestones"=>"0", "users_goals"=>"0", ...}
h1.select { |key, value| value == '1' } #=> {"admin_milestones"=>"1", "admin_goals"=>"1", ...}

返回值取决于您的Ruby版本。Ruby 1.8返回一个数组,而Ruby 1.9返回类似于上面示例中的哈希表。


此答案需要代码通过哈希表两次。对于短哈希可能不是问题,但需要注意。 - Josh

0

类似于https://dev59.com/-GMk5IYBdhLWcg3w7CKX#56164608,您可以使用group_by,但使用then。在这种情况下,您将避免实例化额外的变量。

{
  "admin_milestones" => "1",
  "users_milestones" => "0",
  "admin_goals" => "1",
  "users_goals" => "0",
  "admin_tasks" => "1",
  "users_tasks" => "0",
  "admin_messages" => "1",
  "users_messages" => "0",
  "admin_meetings" => "1",
  "users_meetings" => "0"
}.then { |h| h.keys.group_by { |k| h[k] } }

{"1"=>["admin_milestones", "admin_goals", "admin_tasks", "admin_messages", "admin_meetings"],
 "0"=>["users_milestones", "users_goals", "users_tasks", "users_messages", "users_meetings"]}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接