2

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

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

我如何进行一些操作,例如查找 AAA 的费率,或者查看我是否有 ALLSTAR 的费率,如果费率不存在,我希望能够添加它,我知道我可以使用 into 或 conj 添加它。但我主要担心的是发现我的地图有一个特定的名称,如果存在名称,我需要将速率更新为新值。

4

3 回答 3

2

这是一种方法:

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

这就是说:返回等于testVMap的第一件事。 定义一个函数,用作为它的函数参数。这部分返回每个映射的值的值。:name"GEICO"#(... % ...)%(:name %):name

如果可能有多个“GEICO”地图,并且您想要它们,请使用filter而不是some.

这是另一个版本:

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

您可能也想使用update

编辑:例如:

(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

于 2015-09-08T18:28:31.473 回答
1

与其直接告诉您如何执行此操作,不如让我向您展示如何找到这种功能。

这两个网站的功能结构很好:

现在您要处理的通常是一个集合,如果这不能满足您的要求,您可以寻找特定的向量操作。但首先应该是收藏。然后,您将在两个站点中看到内容测试部分。

现在您有以下候选人:

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

这里的合适人选是some

(some (comp (partial = "AAA") :name) testVMap)
;; => true
于 2015-09-08T18:28:56.290 回答
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}))

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

于 2015-09-08T18:29:01.723 回答