Fastest/One-liner way to collect duplicates in Rub

2020-07-13 08:07发布

What's the fastest/one-liner way to convert an array like this:

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

...into an array of objects like this:

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

标签: ruby arrays
4条回答
做自己的国王
2楼-- · 2020-07-13 08:23

super basic, finally understand inject:

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

Not totally there, but almost

查看更多
我想做一个坏孩纸
3楼-- · 2020-07-13 08:24

To achieve your desired format, you could append a call to map to your solution:

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

Although it still is a one-liner, it starts to get messy.

查看更多
We Are One
4楼-- · 2020-07-13 08:39

Requires 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}
查看更多
淡お忘
5楼-- · 2020-07-13 08:40
array.inject(Hash.new(0)) {|h,v| h[v] += 1; h }

Not a huge difference but I prefer to be explicit with what I am doing. Saying Hash.new(0) replaces {} and h[v] ||= 0

查看更多
登录 后发表回答