Ruby哈希按值分组

7
我有一个包含学生姓名和成绩的Ruby哈希表,如下所示。
student_marks = {
    "Alex" => 50,
    "Beth" => 54,
    "Matt" => 50
}

我正在寻找一个根据学生分数进行分组的解决方案。

{
    50 => ["Alex", "Matt"],
    54 => ["Beth"]
}

我尝试过使用group_by,但是它没有给我想要的结果。以下是使用group_by的结果。
student_marks.group_by {|k,v| v}
{50=>[["Alex", 50], ["Matt", 50]], 54=>[["Beth", 54]]}

提前感谢您。

4个回答

6
我会这样做:
student_marks.group_by { |k, v| v }.map { |k, v| [k, v.map(&:first)] }.to_h
#=> { 50 => ["Alex", "Matt"], 54 => ["Beth"]}

这非常有帮助。谢谢 :) - Sambit

6
student_marks.group_by(&:last).transform_values { |v| v.map(&:first) }
  #=> {50=>["Alex", "Matt"], 54=>["Beth"]}

Hash#transform_values 是 Ruby MRI v2.4.0 中首次亮相的。


这里报错了:undefined method transform_values' for {50=>[["Alex", 50], ["Matt", 50]], 54=>[["Beth", 54]]}:Hash (NoMethodError) - Rajagopalan
@Rajagopalan,我刚刚进行了一次编辑,我希望这可以解释为什么你会收到“无方法错误”的消息。每当代码对一个人(就像它显然对我有效)有效,但对另一个人(你)无效时,这通常是版本问题。我使用的是v2.5.1。 - Cary Swoveland

4
另一种方法可能是:
student_marks.each.with_object(Hash.new([])){ |(k,v), h| h[v] += [k] }
#=> {50=>["Alex", "Matt"], 54=>["Beth"]}

1
另一种简单的方法。
student_marks.keys.group_by{ |v| student_marks[v] }
{50=>["Alex", "Matt"], 54=>["Beth"]}

确实,这是一种更简单的方法。 - Sambit

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