Как мне вести подсчет всех элементов внутри хэшей, которые находятся внутри массива?

#ruby

#ruby

Вопрос:

В принципе, у меня есть массив, который содержит 3 хэша. Я хочу подсчитать и вернуть каждый ключ и значение внутри хэшей, которые включают любые дубликаты. Код приведен ниже, я сделал первый черновик кода, как вы можете видеть сами ниже.

 my_array = [{:name => "blake"}, {:name => "blake"}, {:name => "ashley"}]
 #Count the number of times each element appears inside the hash
 #so the output should have the number of times the :names, "blake" and "ashley" element appears
 #EXPECTED OUTPUT: :name = 3, "blake" = 2, "ashley" = 1

def getOccurances(array)
  array.group_by{|v| v[:name]}.map{|k,v| {name: k, count: v.length}}
end 

getOccurances(my_array)
#ACTUAL OUTPUT: {:name => "blake", :count => 2}, {:name => "ashley", :count => 1}
  

Комментарии:

1. В чем ваш вопрос? Работает ли ваш код? Чего ожидать, каков фактический результат?

2. мой вопрос в том, как мне подсчитать каждый элемент внутри хэша, указанного в коде. Итак, результат должен быть:name = 3, «blake» = 2, «ashley» = 1. Это то, что я хочу от кода. Фактический результат моего кода закомментирован выше, как вы можете видеть.

3. Хорошо, итак, вы хотите также считать ключи как значения. Я бы рекомендовал вам обновить свой вопрос, чтобы прояснить это. Если ваш бонусный комментарий должен это объяснить, это слишком неясно.

4. my_array.group_by { |v| v[:name] }.map { |k, v| [k, v.length] }

Ответ №1:

Вы можете сопоставить каждый хэш с массивом пар [key, val], затем сгладить и каждое вхождение:

 [{:name => "blake"}, {:name => "blake"}, {:name => "ashley"}].
    map(amp;:to_a).flatten.
    reduce(Hash.new { 0 }) {|o, v| o[v]  = 1; o }
  

Аргумент reduce — это хэш, инициализированный блоком, поэтому значение неинициализированных ключей по умолчанию равно 0; мы просто перебираем сглаженные записи и накапливаем количество значений.

Ответ №2:

 my_array.each_with_object(Hash.new(0)) { |g,h| h[g[:name]]  = 1 }.
         map { |k,v| { name: k, count: v } }
  #=> [{:name=>"blake", :count=>2}, {:name=>"ashley", :count=>1}]
  

Примечание:

 my_array.each_with_object(Hash.new(0)) { |g,h| h[g[:name]]  = 1 }
  #=> {"blake"=>2, "ashley"=>1}