Accessing the last key–value pair in a Ruby (1.9) hash
Solution 1
Nothing built in, no. But you could monkey-patch one if you were so inclined (not usually recommended, of course):
class Hash
def last_value
values.last
end
end
And then:
hash.last_value
Solution 2
Hash have a "first" method, but that return the first pair in array mode, for last, you can try:
my_hash.to_a.last
this return last pair in array mode like "first method"
Solution 3
One more alternative that I'm using myself:
hash[hash.keys.last]
which works out better when you want to directly assign a value onto the last element of the hash:
2.4.1 :001 > hash = {foo: 'bar'}
=> {:foo=>"bar"}
2.4.1 :002 > hash[hash.keys.last] = 'baz'
=> "baz"
2.4.1 :003 > hash.values.last = 'bar'
NoMethodError: undefined method `last=' for ["baz"]:Array
Did you mean? last
from (irb):3
from /home/schuylr/.rvm/rubies/ruby-2.4.1/bin/irb:11:in `<main>'
Solution 4
I just did this for a very large hash:
hash.reverse_each.with_index do |(_, value), index|
break value if (index == 0)
end
Related videos on Youtube
davidchambers
Updated on August 03, 2020Comments
-
davidchambers almost 4 years
As of Ruby 1.9, hashes retain insertion order which is very cool. I want to know the best way to access the last key–value pair.
I've written some code which does this:
hash.values.last
This works and is very easy to comprehend, but perhaps it's possible to access the last value directly, rather that via an intermediary (the array of values). Is it?
-
Constant Meiring almost 9 yearsThis is an awesome solution!
-
Janosch about 6 yearsThis is about 2-3 times faster:
v = hash.each_value.reverse_each.next rescue StopIteration
. Still 2-3 times slower thanhash.values.last
for 100M entries, though. -
Janosch about 6 yearsLooking up why this is so slow, I found that
#reverse_each
only makes sense on Arrays. Hash and other Enumerables first create an intermediate Array when#reverse_each
is called, in the case of Hash one with all keys and values. -
Edgar Ortega almost 6 yearsIn new Ruby versions you could also do
hash.values.last
-
sjagr almost 6 years@EdgarOrtega that's exactly what davidchambers was using and led them to asking this question.
-
Edgar Ortega almost 6 years@sjagr 😅, I was pointing to this specific question, but yeah, you're right!
-
sjagr almost 6 years@EdgarOrtega the power of my answer is that you can easily do this
hash[hash.keys.last] = 'bar'
whereas you cannot do thishash.values.last = 'bar'