Создание хэша из массива строк - PullRequest
1 голос
/ 08 апреля 2019

Я новичок в Ruby (и вообще пишу код) и пытаюсь преобразовать массив в хеш, ключи - это слова, а значения - это количество раз, когда слова встречаются в массиве (например, «банан» => 1, "манго" => 2 и т. Д.).

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

array = %w(banana pear mango kiwi mango)

hash1 = array.each_with_object(Hash.new(0)) do |word, count|
  hash1[word] = count
  count += 1
  return hash1
end

puts hash1

Но код не работает вообще. Может кто-нибудь объяснить мне, почему нет, и что я должен изменить?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 08 апреля 2019

Чтобы ваш код работал, вам нужно исправить способ, которым вы пользуетесь each_with_object.

array = %w(banana pear mango kiwi mango)

hash1 = array.each_with_object(Hash.new(0)) do |word, counts|
  counts[word] += 1
end

puts hash1

Hash.new(0) - это хеш, который возвращает ноль при считывании неизвестного ключа.Итак, что вы делаете здесь - это заполняете его, перебирая array и увеличивая счетчик для каждого ключа на единицу.

Я рекомендую прочитать подробнее о Reduce и each_with_object, чтобы понять их использование.

Ответ Фабио более идиоматичен, но я просто хотел показать, как исправить ваш код, а не переписать его.

1 голос
/ 09 апреля 2019

Не знаю, эффективен ли он или нет, но альтернативным способом %w[banana pear mango kiwi mango].group_by{|x| x}.map{|key, values| [key, values.length]}.to_h

1 голос
/ 08 апреля 2019

С последними рубинами (itself и transform_values методы) вы можете сделать:

%w(word one two word).group_by(&:itself).transform_values(&:length)
# => {"word"=>2, "one"=>1, "two"=>1}

Где

.group_by(&:itself)
# returns => {"word"=>["word", "word"], "one"=>["one"], "two"=>["two"]}

.transform_values(&:length)
# returns => {"word"=>2, "one"=>1, "two"=>1}
0 голосов
/ 08 апреля 2019

Хотя вы можете следить за комментариями выше для исправления вашего кода, мне понравилось предоставить эту альтернативу:

array.zip.group_by(&:first).transform_values(&:size)
#=> {"banana"=>1, "pear"=>1, "mango"=>2, "kiwi"=>1}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...