
[英]How do I return a clojure map with fixed keys and conditional values?
[英]How do I conditionally update keys and values in a Clojure map based on the key name?
我有一个 map,键是字符串。 如果密钥包含单词“kg”,我想将该值乘以 2.2,然后将密钥中的“kg”替换为“lb”。 我不知道如何以可以有条件地更新它的方式迭代 map。
示例 map:
{"id" ("7215" "74777" "7219"),
"weight-kg" ("150" "220" "530"),
"time-seconds" ("1900" "2" "770")}
所需 output
{"id" ("7215" "74777" "7219"),
"weight-lb" ("330" "485" "1168"),
"time-seconds" ("1900" "2" "770")}
我试过update
for
map
和reduce-kv
。 项目需求是不使用字符串库,所以才会有re-find
。 这些只是改变价值观的尝试。 由于我无法更改值,因此我没有尝试更改密钥。
(defn kg->lb [m k]
(if (re-find #"kg" k)
(map #(update m % * 2.2))))
(defn kg2->lb2 [m]
(reduce-kv #(if (re-find #"kg" %)
(update % * 2.2)) {} m)
(map #(if (re-find #"kg" %)
(update % * 2.2)) m)
(for [k (keys m)]
(if (re-find #"kg" k)
(update m k #(* % 2.2))))
数据:
(def data {"id" ["7215" "74777" "7219"],
"weight-kg" ["150" "220" "530"],
"time-seconds" ["1900" "2" "770"]})
助手 function 将字符串(kg 数量)转换为字符串(lb 数量):
(defn kg->lb [kg-string]
(-> kg-string
parse-long
(* 2.2)
int
str))
最重要的 function 是reduce-kv
。
如果您在键中找到"kg"
,您将用"lb"
和 map helper function 替换所有值。
如果您在密钥中没有找到"kg"
,您将直接关联该条目而无需更改。
(reduce-kv (fn [m k v]
(if (re-find #"kg" k)
(assoc m (str/replace k #"kg" "lb")
(map kg->lb v))
(assoc m k v)))
{}
data)
我想我通过了项目要求是不使用字符串库,除了(str/replace k #"kg" "lb")
,你可以用String/replace
interop: (.replace k "kg" "lb")
。
(defn update-entry [[k v]]
(if (re-find #"kg" k)
[(.replace k "kg" "lb") (map kg->lb v)]
[k v]))
(->> data
(map update-entry)
(into {}))
传感器版本:
(into {} (map update-entry) data)
我会做一些不同的。 首先,我使用 Java function Long/parseLong
将字符串转换为整数:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test)
(:require
[tupelo.core :as t]
))
(defn parse-vec-longs
[v]
(mapv #(Long/parseLong %) v))
(verify
(is= (parse-vec-longs ["150" "220" "530"])
[150 220 530]))
然后我会编写代码将 kg vals 转换为 lb vals。 最后,只需使用dissoc
去掉 kg 数据,然后assoc
添加新的 lb 数据:
(defn convert-kg-lb
[data]
(let-spy-pretty [kg-vals (get data "weight-kg")
lb-vals (mapv #(Math/round (* 2.2 %)) kg-vals)
result (t/it-> data
(dissoc it "weight-kg")
(assoc it "weight-lb" lb-vals))]
result))
(verify
(let [data-str {"id" ["7215" "74777" "7219"]
"weight-kg" ["150" "220" "530"]
"time-seconds" ["1900" "2" "770"]}
data-parsed (t/map-vals data-str #(parse-vec-longs %))
expected-parsed {"id" [7215 74777 7219]
"weight-kg" [150 220 530]
"time-seconds" [1900 2 770]}
expected-out {"id" [7215 74777 7219]
"weight-lb" [330 484 1166]
"time-seconds" [1900 2 770]}
result (convert-kg-lb data-parsed)]
(is= data-parsed expected-parsed)
(is= (spyx-pretty result) (spyx-pretty expected-out))))
通常,您还会用关键字替换所有字符串键,因此"lb"
=> :lb
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.