【问题标题】:Updating a map that is nested a couple layers in lists in clojure更新嵌套在clojure列表中的几个图层的地图
【发布时间】:2015-11-26 22:11:43
【问题描述】:

我是函数式编程的新手,我正在尝试弄清楚如何实现以下目标。

我在 Clojure 中有一个数据结构:

  [
    [
      { 
        :key1 "val1",
        :key2 [
                { :type "D", ... },
                { :type "A", ... },
                { :type "B", ...}
              ]
         ...
       }
    ]
  ]

我想要做的是保持与所有数据相同的整体数据结构。但是,我希望“key2”列表中的对象按“类型”排序。

看了一些教程,我有这么多:

(doseq [currentList myDataStructure]
  (doseq [currentItem currentList]
    (println (get currentItem :key2))
)))

顺便说一句,doseq 是一种遍历列表的好方法吗?我看到 Clojure 会通过递归循环遍历数据结构。对我来说,将帧添加到堆栈中只是为了遍历一个列表似乎有点奇怪。

【问题讨论】:

  • recur 的调用不会将帧添加到堆栈中
  • 哈哈!谢谢你让我知道! :D
  • 如果您只想要副作用,doseq 是一个不错的选择,但您可以使用单个 doseq 来做到这一点。您还需要sort

标签: data-structures clojure functional-programming


【解决方案1】:

您可以使用update-in

(def x  [[{:key1 "val1",
           :key2 [{:type "D"}
                  {:type "A"}
                  {:type "B"}]}]])

(update-in x [0 0 :key2] (partial sort-by :type))

【讨论】:

  • 不是 OP 的要求,Michiel,虽然我最初也是这么想的。
  • @Mars 我重新阅读了这个问题,但我仍然认为这是问题所在。 “我想要做的是保持与所有数据相同的整体数据结构。但是,我希望“key2”列表中的对象按“类型”排序。”
  • Michiel,你正确理解了这个问题! :D 这很有帮助。我现在正在尝试动态应用更新 - 我的意思是,我不想指定索引 (0 0),而是为所有 (0, n) 执行此操作。
  • @Beebunny 请更新您的问题以包含此新要求。
【解决方案2】:

这是specter 的完美用例:

(sp/transform [sp/FIRST sp/ALL :key2] (partial sort-by :type)
  [
   [
    {
     :key1 "val1",
     :key2 [{:type "D", :v 1},
            {:type "A", :v 3},
            {:type "B", :v 89}]}
    {
     :key1 "val3",
     :key2 [{:type "Z", :v 10},
            {:type "A", :v 30},
            {:type "B", :v 890}]}
    ]
   ])
;;=> [[{:key1 "val1", :key2 ({:type "A", :v 3} {:type "B", :v 89} {:type "D", :v 1})}

;;     {:key1 "val3", :key2 ({:type "A", :v 30} {:type "B", :v 890} {:type "Z", :v 10})}]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多