2017-07-14 15 views
5

मेरे पास वेक्टर [[[1 2] [3 4]] [[5 6] [7 8]] [9 10] 11] है। मैं इस वेक्टर में एक फ़ंक्शन लागू करना चाहता हूं लेकिन डेटा संरचना को रखना चाहता हूं।क्लोजर - वैक्टर के वेक्टर के लिए एक फ़ंक्शन लागू करना

उदाहरण के लिए मैं प्रत्येक नंबर पर 1 जोड़ना चाहता हूं लेकिन परिणाम को [[[2 3] [4 5]] [[6 7] [8 9]] [10 11] 12] परिणाम प्राप्त करने के लिए डेटा संरचना रखना चाहता हूं। क्या यह संभव है?

मैं

(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 उपयोग करने के लिए है, लेकिन मुझे यकीन है कि अगर यह सही है नहीं कर रहा हूँ लेता है।

किसी भी मदद की बहुत सराहना की जाएगी

उत्तर

6

आप postwalk उपयोग कर सकते हैं:

(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)) 
4
भी

क्लासिक पुनरावर्ती समाधान है ज्यादा नहीं और अधिक कठिन:

(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]] 
0

एक और अपनी समस्या को हल करने के लिए जिस तरह से Specter के माध्यम से है। आपको तब एक और निर्भरता की आवश्यकता है, लेकिन यह एक उपयोगी पुस्तकालय हो सकता है।

(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]) 

आप इसे अधिक जटिल परिचालन करने के लिए बढ़ा सकते हैं। इस उपयोग के लिए सामान्य क्लोजर पर्याप्त है।

(specter/transform [TreeWalker] inc data) 
;; => [[[2 3] [4 5]] [[6 7] [8 9]] [10 11] 12] 
संबंधित मुद्दे