我想创建一个像
这样的地图{:a 1
:b 2 ;;in some condition
:c 3 ;;in some other condition
}
但我不知道如何在地图结构中将[:b 2]
之类的列表更改为:b 2
。
以下是我尝试的一些错误案例:
{:a 1
(if (is condition1) [:b 2])
(if (is condition2) [:c 3])
;...
}
{:a 1
(map indentity (if (is condition1) [:b 2]))
(map indentity (if (is condition2) [:c 2]))
;;...
}
我试过的只会返回一个不是参数的序列。
有没有办法在没有宏的情况下处理?
答案 0 :(得分:3)
(into {} [{:a 1}
(if (is condition1) [:b 2])
(if (is condition2) [:c 3])])
这样做是因为如果is condition1
为false,则if
表达式将返回nil
,conj
会在地图上忽略该表达式。
答案 1 :(得分:1)
这是一种方法:
(fn [cond1 cond2]
(into
{:a 1}
(map
(fn [[c e]] (when c e))
[[cond1 [:b 2]] [cond2 [:c 3]]])))
您可能希望传入与条目对相关的条件表。
答案 2 :(得分:0)
我认为merge
是个不错的选择。
(merge {:a 1}
(if condition1 {:b 2})
(if condition2 {:c 3}))
答案 3 :(得分:0)
要回答原始问题,即将一对[:b 2]
添加到地图中,您只需使用conj
:
user> (conj {:a 1} [:b 2])
{:b 2, :a 1}
现在,如果您只想在条件(谓词)为真时添加一对,您可以拥有一个函数,例如:
(defn conj-if-value-is-positive [m kv-pair]
(if (< 0 (second kv-pair))
(conj m kv-pair)
m))
user> (conj-if-value-is-positive {:a 1} [:b 2])
{:b 2, :a 1}
接下来,让我们假设您有一个要添加到地图的对列表,具体取决于相同的条件,您可以reduce
对序列:
user> (reduce conj-if-value-is-positive {:a 1} '([:b 2] [:c 3] [:d -1]))
{:c 3, :b 2, :a 1}
[:d -1]
未添加到地图中,因为它不符合条件。
事实上,函数conj-if-value-positive
不是很通用,可以分解为单独的步骤:
e.g。
user> (reduce (fn [m p] (conj m p))
{:a 1}
(filter (fn [[k v]] (pos? v)) '([:b 2] [:c 3] [:d -1])))
{:c 3, :b 2, :a 1}
在您的示例中,您希望在不同的对上有不同的条件。这可以通过减少[[key value] predicate]
的序列来实现。