Hacker News new | past | comments | ask | show | jobs | submit login

Are hashes guaranteed to be ordered in some way (not just incidentally implemented that way, but specified so that changing it in the future would be considered breaking)? I thought they weren't, in which case there wouldn't really be any obvious way to define `last`, but I might be mistaken



`{}.first` works, so no reason why `{}.last` shouldn't. I would argue, though, that it's best not to rely on hashes for ordering, though that's a relatively loose preference, and I've certainly use it for quick 'n' dirty scriptss


Ruby hashes have been intentionally ordered since Ruby 1.9, which is ~15 years now.


Yep, as I described in another comment I just don't like to exploit that, but it's more of a personal preference. It's cool by me if others choose to.


I agree that it's conceptually weird, but since Ruby guarantees the ordering, you might as well have features for it.


The best feature of `Hash` maintaining insertion order is that `Set` does too, since a `Set` is a `Hash` with all-`true` values: https://github.com/ruby/ruby/blob/3539da64fc42d6eb76f1d4c3cc...


Ya, it's one of things you have to make a team/org-level call on.

For me, ruby is full of a lot of little conveniences that shouldn't necessarily be used in production systems. I always cry loud that code should be quickly "scannable", and the data-structures we choose to use can help a lot in the quicker understanding an unfamiliar piece of code.

But I stress again: these types of decisions are best left up to the team or org. It's ultimately low-stakes.


key ordering is something to rely on now, in Ruby as well as in JavaScript and Python

That ship has sailed - it was partly for the convenience of debugging, but the general purpose dict is now ordered.

It's only by insertion order - it's expensive to change the order - but the order can by relied upon and is being used.

Edit: some detail on changing the order - you can either remove all the key/value pairs up to the first one you want to change and add them back, or you can create a new dict with the pairs in the desired order. With Rust you can choose whether or not to have insertion order preserved https://stackoverflow.com/questions/42723065/how-to-sort-has...


Ya, my preference still stands whether the ship is docked or not. As you point out: it's good for debugging. As I mentioned, I like it for quick things in throwaway scripts. I don't like it in production code because when I'm reading something quickly that I don't care to deeply understand: Hashes are records and arrays order ordered lists. I very much like the way Rust does it (and I like a lot of what I've seen in Rust)--if we had `OrderedHash` in Ruby, I will feel completely different.


That seems arbitrary. I would consider that "politics" and like a place that had a rule to treat hashes as unordered a bit less.


I already implied it was politics by saying that it is something that needs to be determined at the team/org level.

I don't feel it's arbitrary, though, and to get a little clever about it I feel that ordered hashes are arbitrary and that's why I don't like to rely on it in _production_ code.

"Records" (aka hashes, aks dicts, aka maps, etc) are inherently unordered. Relying on insertion order or keyed values is super brittle.

So again, the fact that they are ordered is super convenient! It shines in one-off, temporary situations like debugging or writing a quick script to group something by a specific value without having to do any further sorting. But I don't believe it should ever be replied on in a production system, just for the fact that if the order ever changes, there are possibly many places that have to change.


I get that it's deterministic, but I can't really think of when I would use that for solving real programming tasks?

If it was sorted by a criteria of my choosing, sure. But I don't know when I last cared about insertion order...


Might be some kind of linked list like implementation under the hood. Getting the first element is performant but traversing everything to find the last one would be slow.


That's very unlikely.

Even for singly linked lists, implementations for general purpose use usually keep pointers to the first and last elements so that you can use it as an O(1) FIFO queue, as well as prepend in O(1) time.

If you only keep a pointer to the head of the linked list, then it can be practically used a LIFO queue (stack), and a few other corner cases, but not much else. (A FIFO isn't very useful if adding an item is O(1) but removing an item is O(N), or vice versa.)



Ruby hashes are ordered, per the docs.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: