问题
How can I keep order in array-map? Array-map with a length above 8 behaves completely different in Clojure and Clojurescript. Example:
cljs
(array-map :a true :c true :d false :b true :z false :h false
:o true :p true :w false :r true :t false :g false)
-> {:o true, :p true, :r true, :t false, :w false, :z false, :a true, :b true, :c true, :d false, :g false, :h false}
clj
(array-map :a true :c true :d false :b true :z false :h false
:o true :p true :w false :r true :t false :g false)
-> {:a true :c true :d false :b true :z false :h false :o true :p true :w false :r true :t false :g false}
回答1:
Update:
As of release 2371, non-higher-order calls to cljs.core/array-map
are backed by a macro which emits hash maps for > 8 key-value pairs. See CLJS-873 for ticket + patch.
(Original answer follows.)
The most likely explanation is that you're doing this at the REPL. ClojureScript's standard REPL, as implemented in the (Clojure) namespace cljs.repl
, operates by receiving string representations of returned values from the JS environment, reading them to produce Clojure data and printing them back out again. See line 156 of src/clj/cljs/repl.clj in ClojureScript's sources (link to release 2371).
When the return value of an expression entered on the REPL is a large array map – or a sorted map, or a data.avl sorted map – reading its string representation will produce a hash map on the Clojure side. Needless to say, when this hash map is then printed, the original ordering is lost.
To confirm whether this is indeed what is happening, try doing this at the REPL (copied & pasted from a ClojureScript REPL session in a current checkout):
ClojureScript:cljs.user> (array-map 1 2 3 4 5 6 7 8 9 10 11 12 13 14)
{1 2, 3 4, 5 6, 7 8, 9 10, 11 12, 13 14}
ClojureScript:cljs.user> (array-map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18)
{7 8, 1 2, 15 16, 13 14, 17 18, 3 4, 11 12, 9 10, 5 6}
ClojureScript:cljs.user> (seq (array-map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18))
([1 2] [3 4] [5 6] [7 8] [9 10] [11 12] [13 14] [15 16] [17 18])
ClojureScript:cljs.user> (hash-map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18)
{7 8, 1 2, 15 16, 13 14, 17 18, 3 4, 11 12, 9 10, 5 6}
Note that calling seq
on your array map does produce the expected result.
来源:https://stackoverflow.com/questions/26349324/clojurescript-array-map-order