【问题标题】:Fastest/One-liner way to collect duplicates in Ruby Array?在 Ruby Array 中收集重复项的最快/单线方法?
【发布时间】:2009-10-01 08:01:58
【问题描述】:

像这样转换数组的最快/单线方法是什么:

[1, 1, 1, 1, 2, 2, 3, 5, 5, 5, 8, 13, 21, 21, 21]

...变成这样的对象数组:

[{1 => 4}, {2 => 2}, {3 => 1}, {5 => 3}, {8 => 1}, {13 => 1}, {21 => 3}]

【问题讨论】:

    标签: ruby arrays


    【解决方案1】:

    要实现您想要的格式,您可以将调用附加到您的解决方案中:

    array.inject({}) { |h,v| h[v] ||= 0; h[v] += 1; h }.map {|k, v| {k => v}}
    

    虽然它仍然是单线,但它开始变得凌乱了。

    【讨论】:

    • 您可以通过使用具有默认值的哈希来稍微清理一下:array.inject(Hash.new(0)) { |h,v| h[v] += 1; h }.map {|k, v| {k => v}}
    • 要对其进行排序(如问题示例中所示),请将.sort_by { |o| o.keys[0] } 添加到其中。 现在很乱。 :)
    【解决方案2】:

    超级基础,终于懂注入了:

    array.inject({}) { |h,v| h[v] ||= 0; h[v] += 1; h }

    不完全存在,但差不多

    【讨论】:

    • 知不知道为什么还要问?
    • 回答自己的问题当然不是违法的。 SO FAQ 甚至说没关系,只要它是问题格式。
    • 帮助其他人找到好的信息。谁来回答并不重要。别担心,我不想四处为我已经准备好的答案写问题:)。
    • 有一个徽章甚至被称为自学者:回答了你自己的问题至少有 3 票赞成,所以这里没有违法。
    【解决方案3】:
    array.inject(Hash.new(0)) {|h,v| h[v] += 1; h }
    

    差别不大,但我更愿意明确说明我在做什么。说Hash.new(0) 替换{}h[v] ||= 0

    【讨论】:

      【解决方案4】:

      需要 1.8.7

      a = [1, 1, 1, 1, 2, 2, 3, 5, 5, 5, 8, 13, 21, 21, 21]
      h = {}
      a.group_by {|e| e}.each {|k,v| h[k] = v.length}
      p h  # => {5=>3, 1=>4, 2=>2, 13=>1, 8=>1, 3=>1, 21=>3}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-07
        • 2015-11-27
        • 1970-01-01
        相关资源
        最近更新 更多