Clojure - Applying a Function to a vector of vectors
我有一个向量
例如,我想为每个数字加1,但保留数据结构以得到结果为
我尝试了
1 2 | (map #(+ 1 %) (flatten [[[1 2] [3 4]] [[5 6] [7 8]] [9 10] 11])) => (2 3 4 5 6 7 8 9 10 11 12) |
但是您可以看到数据结构不相同。
是否存在将
的函数
我以为可能要使用步行道,但我不确定这是否正确。
任何帮助将不胜感激
您可以使用
1 2 3 4 | (require '[clojure.walk :as walk]) (let [t [[[1 2] [3 4]] [[5 6] [7 8]] [9 10] 11]] (walk/postwalk (fn [x] (if (number? x) (inc x) x)) t)) |
经典的递归解决方案也并不困难:
1 2 3 4 5 6 | (defn inc-rec [data] (mapv #((if (vector? %) inc-rec inc) %) data)) #'user/inc-rec user> (inc-rec [1 [2 3 [4 5] [6 7]] [[8 9] 10]]) ;;=> [2 [3 4 [5 6] [7 8]] [[9 10] 11]] |
解决问题的另一种方法是通过Spectre。然后,您确实需要另一个依赖项,但是它可能是一个有用的库。
1 2 3 4 5 6 7 8 9 10 11 | (ns your-ns.core (:require [com.rpl.specter :as specter])) (def data [[[1 2] [3 4]] [[5 6] [7 8]] [9 10] 11]) (specter/defprotocolpath TreeWalker) ;; define path walker (specter/extend-protocolpath TreeWalker ;; stop walking on leafs (in this case long) Object nil ;; when we are dealing with a vector, TreeWalk all elements clojure.lang.PersistentVector [specter/ALL TreeWalker]) |
您可以扩展它以执行更复杂的操作。对于此用例,正常的Clojure就足够了。
1 2 | (specter/transform [TreeWalker] inc data) ;; => [[[2 3] [4 5]] [[6 7] [8 9]] [10 11] 12] |