【问题标题】:clojure: compute a new key/val pair in a map based on other key/val pairsclojure:根据其他键/值对计算映射中的新键/值对
【发布时间】:2019-07-25 22:38:05
【问题描述】:

我有一个表示 DataFrame 的地图向量。我想计算一个新列(向量中所有映射的键/值对)。需要一些帮助才能以最有效和惯用的方式执行此操作。

(def dt [{:foo 10 :bar 20 :cat "A"}
         {:foo 15 :bar 10 :cat "B"}
         {:foo 12 :bar 15 :cat "C"}
         {:foo 16 :bar 22 :cat "A"}
         {:foo 13 :bar 11 :cat "B"}
         {:foo 10 :bar 19 :cat "C"}])

我想做的是定义 :baz = :foo + :bar。我可以通过如下映射操作完成计算。

(map #(+ (:foo %) (:bar %)) dt)

我更喜欢写一个函数,其中向量是 maps 是最后一个参数,这样我就可以用 thread-last 宏链接操作

类似这样的:

(->> dt
     (filter #(= (:foo %) 10))
     (compute-new-column #(...)))

我是 Clojure 和 FP 的初学者,因此也欢迎任何其他见解。

【问题讨论】:

  • 抱歉,我的尝试不正确/具有误导性。我正在寻找的是 Christian ({:foo 10, :bar 20, :cat "A", :baz 30} {:foo 10, :bar 19, :cat "C", :baz 29}) 的如下输出

标签: clojure


【解决方案1】:

如果我正确理解您的问题,您希望根据:foo:bar 为集合中的每个映射添加一个新的键值对。

(defn compute-new-column [row]
  (assoc row :baz (+ (:foo row) (:bar row))))

然后你可以在你的线程宏中映射这个函数。就像您在过滤器中所做的那样,这也可以通过匿名函数轻松完成。

(->> dt
     (filter #(= (:foo %) 10))
     (map compute-new-column))


({:foo 10, :bar 20, :cat "A", :baz 30} {:foo 10, :bar 19, :cat "C", :baz 29})

【讨论】:

  • 我的偏好是将列名和函数作为参数传递给 compute-new-column 为:(defn compute-new-column [row colname f] (assoc row (keyword colname) (f row)))
  • (keyword :foo) 和 (keyword "foo") 都给出 :foo -- 这就是我想要的
  • @anerjee 如果您正在处理 JSON 并且您在字符串键或关键字方面有不同的世界,请禁用 JSON 的自动“关键字化”。 keyword 接受任何可能导致以后混淆的废话(例如{(keyword "a :b") :c})。跟着弦走就行了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-01
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多