Clojure 如何更改贴图的子贴图的值?
我不熟悉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]
{
: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
是转换器函数