Clojurescript Array-Map order

末鹿安然 提交于 2019-12-22 14:52:54

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!