首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clojure -将函数应用于向量的向量

Clojure -将函数应用于向量的向量
EN

Stack Overflow用户
提问于 2017-07-14 17:43:26
回答 3查看 293关注 0票数 5

我有一个矢量[[[1 2] [3 4]] [[5 6] [7 8]] [9 10] 11]。我想对这个向量应用一个函数,但保留数据结构。

例如,我希望将每个数字加1,但保留数据结构以获得[[[2 3] [4 5]] [[6 7] [8 9]] [10 11] 12]结果。这个是可能的吗?

我试过了

代码语言:javascript
复制
(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)

但是你可以看到数据结构是不一样的。

有没有一个函数可以把(2 3 4 5 6 7 8 9 10 11 12)带到[[[2 3] [4 5]] [[6 7] [8 9]] [10 11] 12]

我想也许可以使用postwalk,但我不确定这是否正确。

任何帮助都将不胜感激

EN

回答 3

Stack Overflow用户

发布于 2017-07-14 17:54:43

您可以使用postwalk

代码语言:javascript
复制
(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))
票数 6
EN

Stack Overflow用户

发布于 2017-07-14 18:25:38

此外,经典的递归解决方案也不会更加困难:

代码语言:javascript
复制
(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]]
票数 4
EN

Stack Overflow用户

发布于 2017-07-18 02:04:23

另一种解决问题的方法是通过Specter。那么您确实需要另一个依赖项,但它可能是一个有用的库。

代码语言:javascript
复制
(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就足够好了。

代码语言:javascript
复制
(specter/transform [TreeWalker] inc data)
;; => [[[2 3] [4 5]] [[6 7] [8 9]] [10 11] 12]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45099733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档