﻿ clojure - ClojureScript zipmap tricks me or what? - DeveloperSite- developersite.org

# clojure - ClojureScript zipmap tricks me or what?

Keywords：clojure

Question:

I use Clojurescript to develop webbrowser-games. (Actually a friend of mine teaches me, we started only a few weeks ago).

I wanted to generate a map in which keys are vectors and values are numbers. For e.g.: {[0 0] 0, [0 1] 1, [0 2] 2, ...}.

I used this formula:

`````` (defn oxo [x y]
(zipmap (map vec (combi/cartesian-product (range 0 x) (range 0 y))) (range (* x y))))
``````

(where combi/ refers to clojure.math.combinatorics).

When it generates the map, key-value pairs are ok, but they are in a random order, like:

{[0 1] 1, [6 8] 68, [6 9] 69, [5 7] 57, ...}

What went wrong after using zipmap and how can i fix it?

Clojure maps aren't guaranteed to have ordered/sorted keys. If you want to ensure the keys are sorted, use a `sorted-map`:

``````(into (sorted-map) (oxo 10 10))
=>
{[0 0] 0,
[0 1] 1,
[0 2] 2,
[0 3] 3,
[0 4] 4,
[0 5] 5,
...
``````

If your map has fewer than 9 keys then insertion order is preserved because the underlying data structure is different depending on the number of keys:

1. `clojure.lang.PersistentArrayMap` for <9 keys
2. `clojure.lang.PersistentHashMap` otherwise.

`array-map` produces a `clojure.lang.PersistentArrayMap` and `sorted-map` produces a `clojure.lang.PersistentTreeMap`. Note that `assoc`ing onto an array map may produce a hash map, but `assoc`ing on to a sorted map still produces a sorted map.

`zipmap` produces a hash-map where order of the keys is not guaranteed. If you want ordered keys you can use either `sorted-map` or `array-map`.

As far as my knowledge goes, you should not rely on Map/Hash/Dictionary for ordering in any languages.

If the order is important but you don't need O(1) lookup performance of the map, a vector of vector pairs is a good option for you.

``````(defn oxo [x y]
(mapv vector (map vec (combi/cartesian-product (range 0 x) (range 0 y))) (range (* x y))))
``````

You will get something like this.

``````=> (oxo 10 10)
[[[0 0] 0] [[0 1] 1] [[0 2] 2] [[0 3] 3] [[0 4] 4] [[0 5] 5] ...]
``````