147

I have this:

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

and I want to get to this: [["a","b","c"],["b","c"]]

This seems like it should work but it doesn't:

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

Any suggestions?

brymck
  • 7,555
  • 28
  • 31
tbrooke
  • 2,137
  • 2
  • 17
  • 25
  • 2
    The answers below are correct (`hash.values` being the better IMO). But I wanted to point out when you provide a block to `Hash#each` it will just return the full value of the hash. If you want to do an operation on each item and return that as an array, use `Hash#collect` or its alias `Hash#map`. More stuff on Enumerables [here](http://ruby-doc.org/core-1.9.3/Enumerable.html). – brymck Mar 05 '12 at 00:54
  • 4
    This question looks strangely familiar... I wonder how many people are working on the same homework assignment right now. – Peter Brown Mar 05 '12 at 02:41

6 Answers6

296

Also, a bit simpler....

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

Ruby doc here

Ray Toal
  • 86,166
  • 18
  • 182
  • 232
  • 3
    +! Nifty! I will upvote despite having a competing answer (using `map`), cos I like this a lot! – Michael Durrant Mar 05 '12 at 00:57
  • 2
    `Hash#values` is not only simpler, but more efficient. Compare `time ruby -e '(1..1000000).reduce({}){|h,i| h.store i,i; h}.values'` with `time ruby -e '(1..1000000).reduce({}){|h,i| h.store i,i; h}.map{|k,v| v}'` – jordanbtucker Aug 02 '12 at 17:11
  • +1 (Dazzled amazingly after I tried your code) I spent one day with no luck removing the index using many methods... All I can say thank you very much!!! :D – Romans 8.38-39 Jan 08 '14 at 03:19
  • 2
    Are the keys printed in the exact order which they occur ? – stack1 Jun 24 '15 at 22:18
52

I would use:

hash.map { |key, value| value }
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
24
hash.collect { |k, v| v }
#returns [["a", "b", "c"], ["b", "c"]] 

Enumerable#collect takes a block, and returns an array of the results of running the block once on every element of the enumerable. So this code just ignores the keys and returns an array of all the values.

The Enumerable module is pretty awesome. Knowing it well can save you lots of time and lots of code.

Jamison Dance
  • 19,896
  • 25
  • 97
  • 99
11

It is as simple as

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

this will return a new array populated with the values from hash

if you want to store that new array do

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

array_of_values
 #=> [["a", "b", "c"], ["b", "c"]]
8
hash  = { :a => ["a", "b", "c"], :b => ["b", "c"] }
hash.values #=> [["a","b","c"],["b","c"]]
karlingen
  • 13,800
  • 5
  • 43
  • 74
mrded
  • 4,674
  • 2
  • 34
  • 36
  • http://stackoverflow.com/posts/12771873/revisions as you can see the formatting of your code was way off – karlingen Oct 10 '15 at 17:43
3

There is also this one:

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

Why it works:

The & calls to_proc on the object, and passes it as a block to the method.

something {|i| i.foo }
something(&:foo)
karlingen
  • 13,800
  • 5
  • 43
  • 74
  • A more in depth explanation http://www.brianstorti.com/understanding-ruby-idiom-map-with-symbol/ – Sylvain Dec 07 '17 at 03:44