在Ruby Array中收集重复项的最快/一线方式?

时间:2009-10-01 08:01:58

标签: ruby arrays

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

[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}]

4 个答案:

答案 0 :(得分:5)

超级基础,终于理解注入:

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

并非完全存在,但差不多

答案 1 :(得分:5)

要获得所需的格式,您可以附加调用以映射到您的解决方案:

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

虽然它仍然是单行,但它开始变得混乱。

答案 2 :(得分:5)

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

没有太大的区别,但我更愿意明确我正在做的事情。说Hash.new(0)取代{}h[v] ||= 0

答案 3 :(得分: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}