按关键字查找地图clojure地图

假设我有一个使用关键字作为关键字的clojure地图:

(def my-car {:color "candy-apple red" :horsepower 450})

我知道我可以通过使用关键字或地图作为函数而另一个作为它的参数来查找与关键字相关联的值:

(my-car :color)
; => "candy-apple red"
(:color my-car)
; => "candy-apple red"

我意识到两种形式都可以在某些情况下派上用场,但是其中之一被认为更直接地使用像上面所示的惯用语?


(:color my-car)是相当标准的。 这有几个原因,我不会涉及所有的原因。 但是这里有一个例子。

因为:color是一个常数,而my-car不是,热点可以完全内联color.invoke(m)的动态分配,这是m.invoke(color) (在某些java伪代码中)无法做到的。 。

如果my-car碰巧有时是带有color域而不是普通映射的记录,情况会更好:clojure编译器可以发出代码来检查“嘿,如果my-car是CarType的一个实例,那么只需返回my-car.color ;否则,执行所有复杂的慢速hashmap查找。“


从库编码标准:

  • 使用关键字优先语法来访问对象的属性:

    (:property object-like-map)
    
  • 使用collection-first语法从集合中提取值(如果集合可能为零,则使用get)。

    (collection-like-map key)
    (get collection-like-map key)
    

  • 我列出了赞成和反对这两种形式的论点。 ( 编辑:添加第三个选项 - (get map :key)这是我的新宠,尽管有点冗长)

    (:键映射)的参数

    1)需要编码标准

    http://dev.clojure.org/display/community/Library+Coding+Standards

    2)映射为零时仍然有效

    > (:a nil)
      nil
    > (nil :a)
      ERROR: can't call nil
    

    ---反驳---如果重点可能为零,其他形式则更好

    > ({:a "b"} nil)
      nil
    > (nil {:a "b"})
      ERROR: can't call nil
    

    3)更好地用于对对象集合进行线程和映射

    (-> my-map
      :alpha
      fn-on-alpha
      :beta
      fn-on-beta
      :gamma
    
    > (def map-collection '({:key "values"} {:key "in"} {:key "collection"}))
    > (map :key map-collection)
      ("values" "in" "collection")
    

    ---反驳---线程的代码结构与往常不同,所以当需要时可以对地图访问应用不同的惯用倾向

    4)潜在的优化效益? (需要验证)

    (map:key)的参数

    1)当键不是关键字或零时不抛出错误

    > ({:a "b"} nil)
      nil
    > (nil {:a "b"})
      ERROR: can't call nil
    > ({"a" "b"} "a")
      "b"
    > ("a" {"a" "b"})
      ERROR: string cannot be cast to IFn
    

    2)与Clojure中的列表访问保持一致

    > ([:a :b :c] 1)
      :b
    > (1 [:a :b :c])
      ERROR: long cannot be cast to IFn
    

    3)与其他形式的对象访问相似

    java>         my_obj  .alpha  .beta  .gamma  .delta
    clj >     ((((my-map  :alpha) :beta) :gamma) :delta)
    clj > (get-in my-map [:alpha  :beta  :gamma  :delta])
    cljs> (aget   js-obj  "alpha" "beta" "gamma" "delta")
    

    4)从相同的地图(单独的行)访问多个键时的对齐方式

    > (my-func
        (my-map :un)
        (my-map :deux)
        (my-map :trois)
        (my-map :quatre)
        (my-map :cinq))
    > (my-func
        (:un my-map)
        (:deux my-map)
        (:trois my-map)
        (:quatre my-map)
        (:cinq my-map))
    

    ---反驳---当从多个地图访问相同的密钥时,对齐更糟糕

    > (my-func
        (:key map-un)
        (:key map-deux)
        (:key map-trois)
        (:key map-quatre)
        (:key map-cinq)
    > (my-func
        (map-un :key)
        (map-deux :key)
        (map-trois :key)
        (map-quatre :key)
        (map-cinq :key)
    

    (get map:key)的参数

    1)如果arg1是map / vector / nil且arg2是key / index / nil,不会导致错误

    > (get nil :a)
      nil
    > (get nil nil)
      nil
    > (get {:a "b"} nil)
      nil
    > (get {:a "b"} :q)
      nil
    > (get [:a :b :c] nil)
      nil
    > (get [:a :b :c] 5)
      nil
    

    2)与其他Clojure函数一致

    > (get {:a "b"} :a)
      :b
    > (contains? {:a "b"} :a)
      true
    > (nth [:a :b :c] 1)
      :b
    > (conj [:a :b] :c)
      [:a :b :c]
    

    3)地图优先的对齐好处

    > (my-func
        (get my-map :un)
        (get my-map :deux)
        (get my-map :trois)
        (get my-map :quatre)
        (get my-map :cinq))
    

    4)通过一次调用就可以使用Get-in进行嵌套访问

    > (get-in my-map [:alpha  :beta  :gamma  :delta])
    > (aget   js-obj  "alpha" "beta" "gamma" "delta")
    

    来源:http://tryclj.com/上的测试

    链接地址: http://www.djcxy.com/p/66875.html

    上一篇: Idiomatic clojure map lookup by keyword

    下一篇: How to repeat string n times in idiomatic clojure way?