Ruby Hash в массив значений

118

У меня есть это:

hash  = { "a"=>["a", "b", "c"], "b"=>["b", "c"] } 

и я хочу добраться до этого: [["a","b","c"],["b","c"]]

Кажется, это должно работать, но это не так:

hash.each{|key,value| value}
=> {"a"=>["a", "b", "c"], "b"=>["b", "c"]} 

Какие-либо предложения?

tbrooke
источник
Ответы ниже верны ( hash.valuesэто лучший ИМО). Но я хотел отметить, что когда вы предоставляете блок, Hash#eachон просто возвращает полное значение хэша. Если вы хотите выполнить операцию с каждым элементом и вернуть его в виде массива, используйте Hash#collectили его псевдоним Hash#map. Подробнее о Enumerables здесь .
brymck 05
3
Этот вопрос выглядит до странности знакомым ... Интересно, сколько людей сейчас работают над одним и тем же домашним заданием.
Питер Браун

Ответы:

261

Также немного попроще ....

>> hash = { "a"=>["a", "b", "c"], "b"=>["b", "c"] }
=> {"a"=>["a", "b", "c"], "b"=>["b", "c"]}
>> hash.values
=> [["a", "b", "c"], ["b", "c"]]

Рубиновый документ здесь

Рэй Тоул
источник
3
+! Острота! Я буду поддерживать, несмотря на то, что у меня есть конкурирующий ответ (использование map), потому что мне это очень нравится!
Майкл Даррант
2
Hash#valuesне только проще, но и эффективнее. Сравнить time ruby -e '(1..1000000).reduce({}){|h,i| h.store i,i; h}.values'сtime ruby -e '(1..1000000).reduce({}){|h,i| h.store i,i; h}.map{|k,v| v}'
jordanbtucker
+1 (Ослепленный изумительно после того, как я попробовал ваш код) Я провел один день безуспешно, удаляя индекс множеством методов ... Все, что я могу сказать, большое спасибо !!! : D
Римлянам 8.38-39 08
2
Ключи напечатаны в том порядке, в котором они расположены?
stack1
43

Я хотел бы использовать:

hash.map { |key, value| value }
Майкл Даррант
источник
3
Я не отрицал его, но это более сложный эквивалент Hash#values.
Марк Томас
1
Да, я также поддержал ответ Рэя. Я счастлив проголосовать за конкурирующий ответ, когда он мне тоже нравится.
Майкл Даррант
3
Я думаю, мы здесь не соревнуемся, а помогаем друг другу, правда? :)
witkacy26 07
Именно то, что я искал, когда пытался создать массив из хэша, используя его ключи в качестве значений. Спасибо :)
Fabian Leutgeb
Полезно, когда вам нужно одновременно выполнить некоторую логику с клавишами .
Крис Сайрефис,
23
hash.collect { |k, v| v }
#returns [["a", "b", "c"], ["b", "c"]] 

Enumerable#collectпринимает блок и возвращает массив результатов однократного выполнения блока для каждого элемента перечисляемого. Таким образом, этот код просто игнорирует ключи и возвращает массив всех значений.

EnumerableМодуль является довольно удивительным. Хорошее знание этого может сэкономить много времени и кода.

jergason
источник
2
Не забывайте, что, как и ответ @Ray Toal, hash.valuesздесь в конечном итоге правильный ответ.
tadman 05
Или hash.map(&:second):)
Яап Хаагманс
4

Это так просто, как

hash.values
#=> [["a", "b", "c"], ["b", "c"]]

это вернет новый массив, заполненный значениями из хэша

если вы хотите сохранить этот новый массив, сделайте

array_of_values = hash.values
#=> [["a", "b", "c"], ["b", "c"]]

array_of_values
 #=> [["a", "b", "c"], ["b", "c"]]
Мелисса Кинтеро
источник
2

Еще есть такой:

hash = { foo: "bar", baz: "qux" }
hash.map(&:last) #=> ["bar", "qux"]

Почему это работает:

&Вызовы to_procна объект, и передает его в качестве блока к методу.

something {|i| i.foo }
something(&:foo)
karlingen
источник
Более подробное объяснение brianstorti.com/understanding-ruby-idiom-map-with-symbol
Sylvain