Recursion 使用Specter递归地改变映射映射中的值

Recursion 使用Specter递归地改变映射映射中的值,recursion,clojure,specter,Recursion,Clojure,Specter,这里是完全的Clojure新手。这是一个简单的问题,但我似乎无法理解: 假设我有一个未知深度的嵌套hasmap,我如何使用Specter的transform()来改变数据结构的值?我想这里需要一个递归路径,但我无法让它工作。一个有效的例子就是我想要的,不幸的是,文档中没有一个 (递归映射上有一个for set val,但我不知道如何将其转换为转换用例) 编辑:请求了更多详细信息,请参见: 我对一种变换形式感兴趣,它可以改变嵌套贴图的所有值(任何深度)。例如,此转换将能够增加以下贴图(以及任何其他

这里是完全的Clojure新手。这是一个简单的问题,但我似乎无法理解:

假设我有一个未知深度的嵌套hasmap,我如何使用Specter的transform()来改变数据结构的值?我想这里需要一个递归路径,但我无法让它工作。一个有效的例子就是我想要的,不幸的是,文档中没有一个

(递归映射上有一个for set val,但我不知道如何将其转换为转换用例)

编辑:请求了更多详细信息,请参见: 我对一种变换形式感兴趣,它可以改变嵌套贴图的所有值(任何深度)。例如,此转换将能够增加以下贴图(以及任何其他嵌套贴图)中的所有值:

我感兴趣的代码行可能如下所示:

(transform <missing selector here> inc data)
(转换公司数据)
使用:


一定要经常学习英语。对于这样简单的东西,只需使用
clojure.walk/postwark

(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require [clojure.walk :as walk]))

(dotest
  (let [data   {:a 1 :b {:c 2 :d {:e 3}}}
        result (walk/postwalk (fn [item]
                                (if (int? item)
                                  (inc item)
                                  item))
                 data)]
    (is= result {:a 2, :b {:c 3, :d {:e 4}}})))

对于更高级的问题,您可能会对该函数感兴趣,该函数允许您检查从根节点到当前节点的路径上的所有项目。

即使您没有让它工作,您的代码也会帮助我们了解您试图做什么,并从那里开始工作。@cfrick我添加了更多详细信息。我想这对任何认识斯佩克特的人都应该很清楚。没有太多的代码可以显示——正如Clojur中的典型情况一样,最简单的代码是
(transform(walker number?)inc{:a1:b{:c2:d{:e3}}})
。它可能过于笼统,但仍然解决了嵌套贴图(以及任何嵌套结构)的情况
(def MAP-NODES
   (recursive-path [] p
     (if-path map?
       (continue-then-stay MAP-VALS p))))
(transform [MAP-NODES MAP-VALS number?] inc data)
(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require [clojure.walk :as walk]))

(dotest
  (let [data   {:a 1 :b {:c 2 :d {:e 3}}}
        result (walk/postwalk (fn [item]
                                (if (int? item)
                                  (inc item)
                                  item))
                 data)]
    (is= result {:a 2, :b {:c 3, :d {:e 4}}})))