Clojure地图矢量

时间:2015-09-08 18:13:43

标签: clojure clojure-repl

我是clojure编程的新手,需要一些帮助。 假设我有一个地图矢量,如图所示。

(def testVMap 
  [ {:name "AAA" :rate 100 } 
    {:name "GEICO" :rate 120 }
    {:name "PROGRESSIVE" :rate 118} ] )

我如何做一些操作,比如找到AAA的费率或者看看我是否有费率,比如ALLSTAR,如果费率不存在我想要能够添加它,我知道我可以添加使用到或者结合 但我主要关注的是发现我的地图有一个特定的名称,如果存在名称,我需要将费率更新为新值。

3 个答案:

答案 0 :(得分:1)

这是一种方法:

(some #(if (= "GEICO" (:name %)) %) testVMap)

说:返回testVMap等于:name "GEICO"的第一件事。 #(... % ...)定义了一个函数,%作为其函数参数。此部分(:name %)会返回每个地图的:name值。

如果可能有多个“GEICO”地图,并且您想要全部,请使用filter代替some

这是另一个版本:

 (some #(and (= "GEICO" (:name %)) %) testVMap)

您可能也想使用update

编辑: e.g:

(map #(if (= "GEICO" (:name %))
          (update % :rate inc)
          %)
testVMap)

此处inc是向数字添加1的函数。您应该使用执行所需转换的函数替换它,例如#(+ 10 %)(partial + 10),这是相同的事情。

#(...)定义的函数检查:name的值是否为“GEICO”,如果是,则使用您提供的函数更新速率(在这种情况下为inc );否则,#(...)会使地图保持不变。

如果从上下文中不能自我解释,我会留给你查看update的文档。

您也可以使用mapv代替map

毫无疑问,您希望将所有这些构建到一个或多个功能中。请记住,函数是Clojure中的东西 - 它们是“数据”,第一类对象等。所以在我使用inc的地方,你可以有一个函数参数,你定义的函数可以接受另一个函数作为它参数,然后第一个函数将在代码的update部分中使用(而不是inc)。

关于添加地图如果你想要的地图不存在:如果你没有处理很长的地图序列,我会考虑在不同的步骤中这样做。请参阅Andre的答案,了解对于测试集合是否包含元素有用的函数名称。

但是,请注意,测试矢量是否包含不存在的内容需要Clojure查看整个矢量。使用Clojure集而不是向量可能更好,或者考虑使用带有(例如):aaa:geico等的外部映射作为键。在这种情况下,请查看函数update-in

答案 1 :(得分:1)

不要直接告诉你如何做到这一点,让我告诉你如何找到这种功能。

这两个网站很好地构建了这些功能:

现在您正在处理的是集合,如果这样做不符合您的要求,您可以查找特定的向量操作。但第一个应该是集合。然后,您会在两个网站中看到内容测试部分。

现在您有以下候选人:

distinct? empty? every? not-every? some not-any?

这里合适的候选人是some

(some (comp (partial = "AAA") :name) testVMap)
;; => true

答案 2 :(得分:1)

查看项目是否存在

(first
  (filter
    (comp #{"AAA"} :name)
    [{:name "AAA" :rate 100}
     {:name "GEICO" :rate 120}
     {:name "PROGRESSIVE" :rate 118}]))

更新结构

如果订单不重要,您可以将结构重新组织为name-> rate的地图。例如:

{"AAA" 100 "GEICO" 120}

然后,您可以使用update-inassoc来更新费率。

如果订单 很重要,您可以执行以下操作:

(mapv
  (fn [{:keys [name] :as v}]
    (if (= name "AAA")
      (assoc v :rate 500)
      v))
  [{:name "AAA" :rate 100}
   {:name "GEICO" :rate 120}
   {:name "PROGRESSIVE" :rate 118}])

添加到您的结构

您可以使用简单的conj添加它。所以你做了像

这样的事情
(if (has-item? struct) ;; has-item would be defined using the first section of this answer
  (update-item struct ...) ;; update-item using the second section of this answer
  (conj struct {:name "AAA" :rate 100}))

当然还有其他选择,但这些是我要去的第一个选择。