Question

In the following hash, I'd like to return the first 'x' values from each key:

my_hash = {
  :key_one =>["one", "two", "three", "four", "five"], 
  :key_two =>["one", "two", "three", "four", "five"]
} 

without changing the structure of the hash, ie, the keys remain the same. expected output when 'x' is 2:

my_hash = {
  :key_one => ["one", "two"], 
  :key_two => ["one", "two"]
} 

The problem is how to do this 'nicely' - I can make a new hash, but this is cumbersome and ugly, even if the number of keys don't grow, which they might.

{
  :key_one => my_hash[:key_one].first(2),
  :key_two => my_hash[:key_two].first(2)
}
Was it helpful?

Solution

my_hash = {
  :key_one =>["one", "two", "three", "four", "five"], 
  :key_two =>["one", "two", "three", "four", "five"]
}

Hash[ my_hash.map { |k,v| [ k, v.first(2) ] } ]

# => {:key_one=>["one", "two"], :key_two=>["one", "two"]}

References:

  • Hash[] constructor
  • Hash is an Enumerable, so has access to Enumerable#map, and iterates through [key,value] pairs.

OTHER TIPS

Another way using Array#take :

my_hash = {
  :key_one =>["one", "two", "three", "four", "five"], 
  :key_two =>["one", "two", "three", "four", "five"]
}

my_hash.map { |k,v| [ k, v.take(2) ] }.to_h
# => {:key_one=>["one", "two"], :key_two=>["one", "two"]}

Also countrybooting:

Hash[ my_hash.map {|key, val| key, val[0...x] } ]

Where x is the number of values you want ;)

Here you go:

my_hash
# => {:key_one=>["one", "two", "three", "four", "five"],
# :key_two=>["one", "two", "three", "four", "five"]}
my_hash.map {|k,v| [k, v.first(2)]}.to_h
# => {:key_one=>["one", "two"], :key_two=>["one", "two"]}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top