Clojurescript数组映射顺序 [英] Clojurescript Array-Map order

查看:131
本文介绍了Clojurescript数组映射顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在数组映射中保持顺序?长度大于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 
: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}
/ pre>

解决方案

更新:



从版本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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆