Какой самый быстрый / однострочный способ преобразования массива выглядит так:
[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}]
Чтобы достичь желаемого формата, вы можете добавить вызов к карте в ваше решение:
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 }
Не большая разница, но я предпочитаю четко указывать, что я делаю. Сказать Hash.new(0) заменяет {} и h[v] ||= 0
Hash.new(0)
{}
h[v] ||= 0
супер базовый, наконец, понять, ввести:
array.inject({}) { |h,v| h[v] ||= 0; h[v] += 1; h }
Не совсем там, но почти
Требуется 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}