【问题标题】:ClojureScript zipmap tricks me or what?ClojureScript zipmap 欺骗了我还是什么?
【发布时间】:2018-02-07 08:44:44
【问题描述】:

我使用 Clojurescript 开发网络浏览器游戏。 (实际上是我的一个朋友教我的,我们才几周前才开始)。

我想生成一个映射,其中键是向量,值是数字。例如:{[0 0] 0, [0 1] 1, [0 2] 2, ...}。

我使用了这个公式:

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

(combi/ 指的是 clojure.math.combinatorics)。

生成map的时候,key-value对是ok的,但是顺序是随机的,比如:

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

使用 zipmap 后出了什么问题,我该如何解决?

【问题讨论】:

    标签: clojure clojurescript


    【解决方案1】:

    Clojure 映射不保证具有有序/排序的键。如果要确保对键进行排序,请使用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,
    ...
    

    如果您的地图的键少于 9 个,则 插入 顺序会被保留,因为基础数据结构会因键的数量而异:

    1. clojure.lang.PersistentArrayMap
    2. clojure.lang.PersistentHashMap 否则。

    array-map 产生一个clojure.lang.PersistentArrayMapsorted-map 产生一个clojure.lang.PersistentTreeMap。请注意,assoc 在数组映射上可能会产生 hash 映射,但 assoc 在排序映射上仍然会产生排序映射。

    【讨论】:

    • “典型的 Clojure 地图”——你知道有什么通用语言,其中 为开箱即用的地图遍历提供了排序保证吗?我怀疑如果它泛指“典型地图”,这也适用。
    【解决方案2】:

    zipmap 生成一个哈希映射,其中键的顺序无法保证。 如果您想要订购的钥匙,您可以使用sorted-maparray-map

    【讨论】:

      【解决方案3】:

      据我所知,您不应依赖 Map/Hash/Dictionary 以任何语言进行排序。

      如果顺序很重要,但您不需要 O(1) 的地图查找性能,那么向量对的向量对您来说是一个不错的选择。

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

      你会得到这样的东西。

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

      【讨论】:

        猜你喜欢
        • 2016-05-20
        • 2012-01-29
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 2011-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多