Clojure 如何更改贴图的子贴图的值?

Clojure 如何更改贴图的子贴图的值?,clojure,Clojure,我不熟悉Clojure和函数式编程,现在我遇到了一个问题。我得到这样一个数据结构: { :service1 \a :service2 \b :service3 \c :default \d :alert-a { :duration "00:00-23:59" :if-alert true :continuous-times 2 :time-interval [2 6 9 15 30 60]

我不熟悉Clojure和函数式编程,现在我遇到了一个问题。我得到这样一个数据结构:

{
 :service1 \a
 :service2 \b
 :service3 \c
 :default \d
 :alert-a {
           :duration "00:00-23:59"
           :if-alert true
           :continuous-times 2
           :time-interval [2 6 9 15 30 60]
           :times -1
           }
 :alert-b {
           :duration "09:00-23:00"
           :if-alert true
           :continuous-times 2
           :time-interval [2 6 9 15 30 60]
           :times -1
           }
 :alert-c {
           :duration "00:00-23:59"
           :if-alert true
           :continuous-times 5
           :time-interval [5]
           :times 1
           }
 :alert-d {
           :duration "00:00-23:59"
           :if-alert true
           :continuous-times 5
           :time-interval [5 15 30 60]
           :times -1
           }
 }
这是从配置文件读取的内容。我想使用
clj time
将所有
:duration
值更改为DateTime对象。所以我可以得到如下结果:

{
 :service1 \a
 :service2 \b
 :service3 \c
 :default \d
 :alert-a {
           :duration DateTime Object
           :if-alert true
           :continuous-times 2
           :time-interval [2 6 9 15 30 60]
           :times -1
           }
 :alert-b {
           :duration DateTime Object
           :if-alert true
           :continuous-times 2
           :time-interval [2 6 9 15 30 60]
           :times -1
           }
 :alert-c {
           :duration DateTime Object
           :if-alert true
           :continuous-times 5
           :time-interval [5]
           :times 1
           }
 :alert-d {
           :duration DateTime Object
           :if-alert true
           :continuous-times 5
           :time-interval [5 15 30 60]
           :times -1
           }
 }
但是数据结构是不变的。这在其他语言中是一个很容易的问题,但现在我不知道在一个下午后如何解决


有人能给我一些建议吗?我使用的是坏的数据结构吗?或者这个问题可以用函数的方式解决

尽管您使用的是不可变的数据结构,但您可以轻松高效地返回基于原始数据结构的新数据结构

在这种情况下,最简单(如果重复)的解决方案是:

(-> m 
  (update-in [:alert-a :duration] parse-duration)
  (update-in [:alert-b :duration] parse-duration)
  (update-in [:alert-c :duration] parse-duration)
  (update-in [:alert-d :duration] parse-duration))
这里要认识到的重要一点是,中的
更新不会改变它所处理的数据结构。相反,它返回一个新的数据结构,并应用修改

线程宏
->
允许通过
操作中的
更新对新数据结构进行线程化,因此最终返回的值是应用了所有更新的原始数据结构

parse duration函数可能看起来有点像这样:

(defn parse-duration 
   "Convert duration in HH:MM-HH:MM format"
    [s]
    (let [[t1 t2] (clojure.string/split s #"-"))
       (Period. (clj-time.coerce/to-date-time t1) 
                (clj-time.coerce/to-date-time t2))) 

尽管您使用的是不可变的数据结构,但可以轻松高效地返回基于原始数据结构的新数据结构

在这种情况下,最简单(如果重复)的解决方案是:

(-> m 
  (update-in [:alert-a :duration] parse-duration)
  (update-in [:alert-b :duration] parse-duration)
  (update-in [:alert-c :duration] parse-duration)
  (update-in [:alert-d :duration] parse-duration))
这里要认识到的重要一点是,
中的
更新不会改变它所处理的数据结构。相反,它返回一个新的数据结构,并应用修改

线程宏
->
允许通过
操作中的
更新对新数据结构进行线程化,因此最终返回的值是应用了所有更新的原始数据结构

parse duration函数可能看起来有点像这样:

(defn parse-duration 
   "Convert duration in HH:MM-HH:MM format"
    [s]
    (let [[t1 t2] (clojure.string/split s #"-"))
       (Period. (clj-time.coerce/to-date-time t1) 
                (clj-time.coerce/to-date-time t2))) 

在函数式编程中,您不修改集合,而是创建新集合,用所需的值替换为新值。幸运的是,Clojure为此提供了一系列有用的函数。因为你的案子应该很有效。它需要一个集合(例如映射)、嵌套键序列和一个函数来应用于由键序列定义的最嵌套的值。例如:

> (def m {:a 1 :b 2 :c {:c1 1 :c2 2}})
#'sandbox5448/m
> m
{:a 1, :c {:c1 1, :c2 2}, :b 2}
> (update-in m [:c :c1] str)
{:a 1, :c {:c1 "1", :c2 2}, :b 2}
注意键序列
[:c:c1]
中的值
1
如何转换为
“1”

因此,将
:alert-a
:duration
字段转换为
DateTime
非常简单:

> (update-in your-map [:alert-a :duration] string-to-date)

其中,
string-to-date
是转换器函数

在函数式编程中,您不修改集合,而是创建新集合,用新集合替换所需的值。幸运的是,Clojure为此提供了一系列有用的函数。因为你的案子应该很有效。它需要一个集合(例如映射)、嵌套键序列和一个函数来应用于由键序列定义的最嵌套的值。例如:

> (def m {:a 1 :b 2 :c {:c1 1 :c2 2}})
#'sandbox5448/m
> m
{:a 1, :c {:c1 1, :c2 2}, :b 2}
> (update-in m [:c :c1] str)
{:a 1, :c {:c1 "1", :c2 2}, :b 2}
注意键序列
[:c:c1]
中的值
1
如何转换为
“1”

因此,将
:alert-a
:duration
字段转换为
DateTime
非常简单:

> (update-in your-map [:alert-a :duration] string-to-date)
其中,
string-to-date
是转换器函数