Let's say I have a hash:
h = {:a=>1, :b=>3, :c=>2, :d=>4}
I want to sort it based on the keys, but I always want :c last. I really don't care the order of the others, as long as :c comes as the final one...
Is there a simple way to do this?
My idea was to get all the keys, remove :c, sort them and place them into a new array, then push :c into the array?
If you don't care about the order, except that "c" is last, I'd use:
hash[:c] = hash.delete(:c)
For instance:
hash = {:d=>4, :c=>2, :b=>3, :a=>1, }
hash # => {:d=>4, :c=>2, :b=>3, :a=>1}
hash[:c] = hash.delete(:c)
hash # => {:d=>4, :b=>3, :a=>1, :c=>2}
Just don't waste your time, or the CPU's, by doing that every time you add something to the hash. Do it just before you need to read the values from the hash.
i dont understand why delete is moving :c to the end of the array
Per the documentation for hashes:
Hashes enumerate their values in the order that the corresponding keys were inserted.
Ruby maintains the insertion order of hashes. They're not sorted by any means, contrary to what some people will tell you. Because it remembers, when we delete
the key, Ruby returns the value, which is then immediately assigned back to :c
in the hash. And, because it's the last thing added, it'll be at the end of the hash.
Your approach would work, as would the following:
Hash[h.sort_by {|k, v| k == :c ? 1 : 0}]
as well as several other approaches. :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With