Clojurescript数组映射顺序 [英] Clojurescript Array-Map order
问题描述
如何在数组映射中保持顺序?长度大于8的数组映射在Clojure和Clojurescript中表现完全不同。示例:
cljs
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} b $ b
clj
(array-map:a true:c true:d false:b true:z false:h false
/ pre>
: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}
解决方案更新:
从版本2371开始,对
cljs.core / array-map
的非高阶调用由发布> 8个键值对的散列映射的宏提供支持。请参阅 CLJS-873 机票+补丁。
(原始答案如下。)
是你在REPL这样做。在Clojure命名空间
cljs.repl
中实现的ClojureScript标准REPL通过接收来自JS环境的返回值的字符串表示来操作,读取它们以产生Clojure数据和打印他们再次退出。请参见 src / clj / cljs / repl第156行
当在REPL上输入的表达式的返回值是大数组映射 - 或者排序地图或 data.avl 排序地图 - 读取其字符串表示形式将产生一个散列图Clojure端。不必说,当打印这个哈希映射时,原始的顺序会丢失。
要确认这是否确实是发生了什么,请尝试在REPL从当前签出的ClojureScript REPL会话中复制和粘贴):
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> (散列图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}
请注意,调用
seq
在数组图上产生预期的结果。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}
解决方案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.这篇关于Clojurescript数组映射顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!