当前位置:  开发笔记 > 编程语言 > 正文

在Clojure中,如何正确更新嵌套映射?

如何解决《在Clojure中,如何正确更新嵌套映射?》经验,为你挑选了0个好方法。

经过多年的Java(和PHP/JavaScript)经验,我刚刚开始学习Clojure.真是个挑战:-)

如何以惯用方式更新值的映射?当我map在地图上使用该函数时,它不返回地图,它返回一个序列.

我正在开发一个小应用程序,我有一个任务列表.我想做的是改变一些单独任务中的一些值,然后更新原始任务列表.以下是我正在测试的任务:

(defrecord Task [key name duration])

(def tasks
  (atom
    {
     "t1" (->Task "t1" "Task 1" 10)
     "t2" (->Task "t2" "Task 2" 20)
     "t3" (->Task "t3" "Task 3" 30)
     }
    ))

我已经使用字符串键将任务放在散列映射中,因此它可以快速,直接地访问映射中的任何任务.每个任务都包含密钥,因此我知道当我将各个任务传递给其他函数时,关键是什么.

更新我正在使用的持续时间,mapupdate-in迭代并有选择地更新每个任务的持续时间,并返回修改后的任务.

这是功能:

(defn update-task-durations
  "Update the duration of each task and return the updated tasks"
  [tasks]
  ; 1) Why do I have to convert the result of the map function,
  ;    from a sequence then back to a map?
  (into {}
    (map
      (fn [task]
        (println task) ; debug
        (update-in
          task
          ; 2) Why do I have to use vector index '1' here
          ;    to get the value of the map entry?
          [1 :duration]
          (fn [duration]
            (if (< duration 20)
              (+ duration 1)
              (+ duration 2)
              )
            )
          )
        ) tasks))
  )

我用这个打印之前/之后的值:

(println "ORIGINAL tasks:")
(println @tasks)

(swap! tasks update-task-durations)

(println "\nUPDATED tasks:")
(println @tasks)

1)我遇到的主要问题是map函数返回一个序列,而不是一个map,所以我不得不再次将序列转换回一个map,into {}这对我来说似乎是不必要和低效的.

有一个更好的方法吗?我应该使用除以外的功能map吗?

我可以更好地安排我的数据结构,同时仍然可以直接访问单个任务吗?

可以使用into {}?将(可能非常大的)序列转换为地图吗?

2)另外,在我的函数参数中,我传递给map函数,每个任务都给我map,作为表格的向量,[key value]当我期望一个地图条目时,所以从我有的地图条目中获取值将以下键传递给我update-in [1 :duration]这看起来有点难看,是否有更好/更清晰的方式来访问映射条目而不是使用向量的索引1?

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有