我是clojure编程的新手,需要一些帮助。 假设我有一个地图矢量,如图所示。
(def testVMap
[ {:name "AAA" :rate 100 }
{:name "GEICO" :rate 120 }
{:name "PROGRESSIVE" :rate 118} ] )
我如何做一些操作,比如找到AAA的费率或者看看我是否有费率,比如ALLSTAR,如果费率不存在我想要能够添加它,我知道我可以添加使用到或者结合 但我主要关注的是发现我的地图有一个特定的名称,如果存在名称,我需要将费率更新为新值。
答案 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-in
或assoc
来更新费率。
如果订单 很重要,您可以执行以下操作:
(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}))
当然还有其他选择,但这些是我要去的第一个选择。