【问题标题】:Clojure array of mapsClojure 地图数组
【发布时间】:2015-09-09 21:45:47
【问题描述】:

我正在尝试在Clojure 中对此类数据进行建模

name: foo    data: bar
name: stack  data: overflow
name: tess   data: ting

我考虑过使用地图,但其中不能有重复的键,这样就行不通了。

是否可以有一组地图,类似于:

[{name: foo,    data: bar} 
{name: stack,  data: overflow} 
{name: tess,   data: ting}]

如果是,您将如何访问数据。例如,您将如何访问data: overflow

您是否必须使用嵌套的get 语句?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    也许我遗漏了一些东西,但看起来你正在重新发明一个地图,而不是 keysvalues 你想要 names em> 和 数据。例如,以下内容足以为您的地图建模:

    (get {"foo" "bar" "stack" "overflow" "tess" "ting"} "stack")
    => "overflow"
    

    现在,如果您的数据更复杂,您当然可以将地图存储在某个键下。 换句话说,您构建了一个映射,其中键是与每个数据关联的名称。假设你有一个这样的向量:

    (def data [{:name "foo"   :data "bar"} 
               {:name "stack" :data "overflow"} 
               {:name "tess"  :data "ting"}])
    

    为了有对应的地图,你可以这样做:

    (reduce (fn [m d] (assoc m (:name d) d)) {} data)
    

    ... 给出:

    {"tess"  {:name "tess" , :data "ting"}, 
     "stack" {:name "stack", :data "overflow"}, 
     "foo"   {:name "foo"  , :data "bar"}}
    

    【讨论】:

      【解决方案2】:

      首先,{:name "foo" :data "overflow"},这是 EDN,不是 JSON;

      第二,对,(def map-array [{:name "foo"} {:name "bar"}])就可以了

      要访问字段,您可以使用 getget-inhttps://clojuredocs.org/clojure.core/get-in

      (get-in map-array [1 :name])
      => "bar"
      

      你也可以这样使用filter函数:

      (first (filter #(= "foo" (:name %)) map-array))
      => {:name "foo"}
      

      编辑: 如果您想摆脱 filter 并获得对地图的恒定访问时间,您应该使用某种 uniq ID:

      (def map-array {:id1 {:name "foo"}
                      :id2 {:name "bar"}})
      (get-in map-array [:id1 :name])
      => "foo"
      
      ;; using threading macro and keyword special power:
      (-> map-array :id2 :name)
      => "bar"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-07
        • 2014-10-18
        • 1970-01-01
        • 1970-01-01
        • 2020-09-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多