Are keys and vals guaranteed to return in the same order?

194 views
Skip to first unread message

Michael Blume

unread,
Apr 17, 2015, 5:40:07 PM4/17/15
to clo...@googlegroups.com

In other people's Clojure code I sometimes see things like

(zipmap
  (map some-fn (keys m))
  (map other-fn (vals m)))

If it were my code I'd be much more inclined to write

(into {}
  (for [[k v] m]
    [(some-fn k) (other-fn v)]))

Is this a to-each-their-own thing or is the latter preferred?

Ambrose Bonnaire-Sergeant

unread,
Apr 17, 2015, 5:43:19 PM4/17/15
to clojure
keys/vals are documented to return the same order as seq. This is a safe assumption.

Thanks,
Ambrose

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ambrose Bonnaire-Sergeant

unread,
Apr 17, 2015, 5:44:40 PM4/17/15
to clojure
Clearly this assumes immutable maps.

Andy Fingerhut

unread,
Apr 17, 2015, 6:17:55 PM4/17/15
to clo...@googlegroups.com
And it assumes that they are _identical_ maps that you are calling keys and vals on.

Equal (via =) not-sorted maps do *not* guarantee that they will have the same seq order as each other, and in some cases do not, due to hash collisions in hash maps having items in a linked list in whatever order they happened to be added to the map.  Similarly for array maps.

Andy

Allen Rohner

unread,
Apr 18, 2015, 3:17:43 PM4/18/15
to clo...@googlegroups.com
One minor quibble is that your example only makes one pass over the data. If the map is big enough, there could be a performance advantage. 

 

Thumbnail

unread,
Apr 19, 2015, 8:49:41 AM4/19/15
to clo...@googlegroups.com
Is order guaranteed?

For any map m,

(= m (zipmap (keys m) (vals m)))


... is guaranteed.

But, for two maps m1 and m2,

(= m1 m2)

... does not imply

(= (seq m1) (seq m2))

Which version to prefer?

It's worth looking at what the Clojure Cookbook does. It uses both patterns, only expanding for into map in the second one. But none of their functions quite matches your case, which I think it would express using zipmap.

Thumbnail

unread,
Apr 19, 2015, 9:20:33 AM4/19/15
to clo...@googlegroups.com
... For example

(let [m1 (array-map 1 2, 3 4)
      m2 (array-map 3 4, 1 2)]
  [(= m1 m2) (= (seq m1) (seq m2))])

=> [true false]
Reply all
Reply to author
Forward
0 new messages