使用clojure'时重复使用部分替代品;s'comp`

使用clojure'时重复使用部分替代品;s'comp`,clojure,functional-programming,Clojure,Functional Programming,“给一个集合” 我想将此转换为: {"key_1" "value_1" "key_2" "value_2"} 这样做的一个功能是: (defn long->wide [xs] (apply hash-map (flatten (map vals xs)))) 我可以使用threading宏简化此过程: (defn long->wide [xs] (->> xs (map vals) (flatten) (apply

“给一个集合”

我想将此转换为:

{"key_1" "value_1" "key_2" "value_2"}
这样做的一个功能是:

(defn long->wide [xs]
    (apply hash-map (flatten (map vals xs))))
我可以使用threading宏简化此过程:

(defn long->wide [xs]
  (->> xs
       (map vals)
       (flatten)
       (apply hash-map)))
这仍然需要明确定义函数参数,除了传递给第一个函数之外,我不会对该参数执行任何操作。然后,我可能会使用
comp
重写此参数以删除此参数:

(def long->wide
  (comp (partial apply hash-map) flatten (partial map vals)))
但是,这需要重复使用
部分
,这对我来说是函数中的大量噪声


clojure中是否有一个函数结合了
comp
->
,因此我可以创建一个更高阶的函数,而无需重复使用partial,而且还需要创建一个新函数?

因为这里的许多答案都没有回答原始问题,但是 建议不同的方法,我也把它放了回去

我会使用reduce和destructuring:

(reduce 
  (fn [m {:keys [key value]}] 
    (assoc m key value)) 
  {} 
  [{:key "key_1" :value "value_1"}, {:key "key_2" :value "value_2"}])
注意,这也适用于字符串键(您在注释中提到过)(注意
:strs
):

另一个(无点)版本,使用关键字时:

(partial (into {} (map (juxt :key :value))))
由于您在评论中提到,您使用的是数据库中的值,因此也有可能切换到仅返回值元组。然后整个操作就是:

(into {} [["key_1" "value_1"]["key_2" "value_2"]])  
还要注意的是,在地图上使用
vals
并期望“插入顺序”是不正确的 危险。小地图只是偶然订购的:

user=> (take 3 (zipmap (range 3) (range 3)))
([0 0] [1 1] [2 2])
user=> (take 3 (zipmap (range 100) (range 100)))
([0 0] [65 65] [70 70])

除了这些好答案之外,还有一个选择:

(apply hash-map (mapcat vals [{:key "key_1" :value "value_1"}, {:key "key_2" :value "value_2"}]))
或:


与clojure完全相同。

解决大多数问题的方法很多

(partial #(reduce (fn [r m] (assoc r (m :key) (m :value)))
                  {}
                  %)))
不确定匿名函数的创建是否违反了您的条件,但这并没有将函数添加到名称空间,因此我认为我应该将其扔掉。这还有一个好处,即不要求输入映射中的键为关键字,因为:key和:value可以替换为任何类型的值,因为映射位于函数中例如:

(partial #(reduce (fn [r m] (assoc r (m "key") (m "value")))
                  {}
                  %)))

如果你想自由点,这将是另一种选择:
(部分进入{}(map(juxt:key:value))
(vals{:value“v1”:key“k1”})
(vs
(={:value“v1”:key“k1”}{:key“k1”:value“v1”})
)是危险的,因为常规地图没有排序(小地图是“偶然的”)@cfrick的函数更可取。如果将数据表示为
[{:value“value\u 1”:key“key\u 1”}{:value“value\u 2”,“key”key“key\u 2”}]
,则
(长->宽数据)
将生成
{“value\u 1”key\u 1”,“value\u 2”key\u 2}
。小心
展平
!@cfrick谢谢你。我没有想到使用
juxt
。我从数据库获取数据,所以我认为要使用它,我必须首先对键进行关键词化,因为键是字符串。@cfrick啊,我意识到我是用关键字写问题的,所以我的问题在这方面具有误导性。
((comp #(apply hash-map %) #(mapcat vals %)) [{:key "key_1" :value "value_1"}, {:key "key_2" :value "value_2"}])
(partial #(reduce (fn [r m] (assoc r (m :key) (m :value)))
                  {}
                  %)))
(partial #(reduce (fn [r m] (assoc r (m "key") (m "value")))
                  {}
                  %)))