58

I would like to use each_with_object on a hash but can't figure out how I should use it. Here is what I have:

hash = {key1: :value1, key2: :value2}
hash.each_with_object([]) { |k, v, array| array << k }

NoMethodError: undefined method `<<' for nil:NilClass

Is it possible to use each_with_object on hashes? If yes, what is the syntax?

sawa
  • 165,429
  • 45
  • 277
  • 381
Pierre-Louis Gottfrois
  • 17,561
  • 8
  • 47
  • 71

3 Answers3

119

Use ():

hash.each_with_object([]) { |(k, v), array| array << k }
apneadiving
  • 114,565
  • 26
  • 219
  • 213
  • 1
    WHere i can find informatin about the `()` in blocks arguments? – Dreeub Sep 22 '17 at 17:51
  • @andfb18 see [Enumerator description](https://ruby-doc.org/core/Enumerator.html#method-i-each_with_object). Blocks and arguments could be puzzling sometimes. I could recommend the most excellent blocks introduction in Chapter 5 of [Head First Ruby](http://headfirstruby.com). – Mr. Tao Oct 02 '17 at 09:47
  • 2
    @andfb18 It's called "Array Decomposition" and you can learn about it [here](https://ruby-doc.org/core-2.4.3/doc/syntax/assignment_rdoc.html#label-Array+Decomposition). – Dwayne Crooks Feb 27 '18 at 19:54
0

For someone who wants to return a new hash:

hash = {"a": 100, "b": 200, "c": 300}

hash.each_with_object({}) { |(k, v), new_hash| new_hash[k] = v if v > 100 } # => {:b=>200, :c=>300}
Ammar Shah
  • 131
  • 2
  • 10
-3

I have idea about that. You can use

output =[]
Hash.each_with_index do |e, index| 
  // do something with e. E is aray. e have 2 items.
  // First item of e is key.
  // Last item of e is value.
  // index start with 0.
  // using << with output here.
end
ThienSuBS
  • 1,574
  • 18
  • 26