2011-11-20 5 views
8

मैं एक सदिश राशि vclojure में, कैसे एक [बड़ी] वेक्टर में चयनित आइटम के लिए एक समारोह को लागू करने के

(def v [1 2 5 8 4 3 8 9 3]) 

मैं चयनित आइटम के लिए समारोह myfn

(defn myfn [x] (+ 1 x)) 

लागू करना चाहते हैं कि मैं उनके सूचकांक idx

(def idx [3 5]) 

मैंनेदेखा हैऔर यह वही नहीं है जो मुझे चाहिए।

आप clojure में MATLAB

v = [1 2 5 8 9 3]; 
idx = [3 5]; 
v(idx) = myfn(v(idx)); 
+0

माफ करना, @yoda, अब यह है। – Ali

उत्तर

9

वेक्टर में क्या करना पसंद है, साहचर्य हैं, ताकि आप कुछ इस तरह कर सकते हैं: (reduce #(update-in %1 [%2] myfn) v idx)

3

अपडेट किया गया क्योंकि मैं सवाल का गलत मतलब निकाला।

(apply assoc v (mapcat #(vector % (myfn (v %))) idx)) 

है कि, assoc के सूचकांक/नई-मान जोड़ों का एक तर्क सूची का निर्माण:

यहाँ एक और समाधान है। मुझे लगता है कि मंगेज के समाधान शायद बेहतर है।


मूल, गलत समाधान

भूल जाते हैं कि वेक्टर v ही अपने सूचकांक की एक समारोह है मत करो। तो:

(map myfn (map v idx)) 

या:

(->> idx (map v) (map myfn)) 

या:

(map (comp myfn v) idx) 

मैं वहाँ भी है एक बहुत ही चालाक शामिल juxt :)

+1

यह मूल सदिश के भीतर उन्हें अद्यतन करने के बजाय किसी नए seq के रूप में संशोधित अनुक्रमित वापस आ जाएगी। – mange

+0

ओह। प्रश्न आउटपुट निर्दिष्ट नहीं करता है, इसलिए गलत व्याख्या करना आसान था। –

2

आप उल्लेख "एक [जवाब यकीन बड़ा] वेक्टर ", तो क्या आप प्रदर्शन के बारे में परवाह करते हैं? आप बाहर transients के बारे में पता लगाने के लिए चाहते हो सकता है:

(persistent! 
    (reduce (fn [v i] (assoc! v i (myfn (get v i)))) 
      (transient v) 
      idx)) 

या, यदि आप शैली पाशन पसंद करते हैं, इस एक ही बात करता है:

(loop [v (transient v), [i & is :as idx] idx] 
    (if (empty? idx) 
    (persistent! v) 
    (recur (assoc! v i (myfn (get v i))) is))) 
+0

कई इंडेक्स अपडेट करते समय यह निश्चित रूप से बेहतर होता है। 'क्षणिक'/'लगातार 'की लागत क्या है? मुझे लगता है कि सूचकांक की एक छोटी संख्या के लिए यह थोड़ा अधिक ओवरहेड होगा। – mange

+0

वे हे (1) के रूप में विज्ञापित कर रहे हैं, और वे बहुत तेजी से होने लगते है।लागत कोड पर प्रतिबंधों में अधिक है: आपको प्राइमेटिव्स के एक अलग सेट का उपयोग करना होगा और अन्य थ्रेड्स को 'क्षणिक' और 'लगातार' के बीच डेटा तक पहुंचने की अनुमति नहीं देनी चाहिए। लेकिन ट्रांजिस्टर इस तरह के कोड के एक छोटे टुकड़े के लिए एक अच्छा मैच है जो एक लूप में डेटा संरचना के कई संपादन करता है। –

+0

हाँ, 'ओ (1)' का मतलब निरंतर ओवरहेड है, इसलिए बड़ी संख्या में उत्परिवर्तन के लिए नगण्य, लेकिन शायद छोटी संख्या के लिए महत्वपूर्ण हो सकता है। मैंने वास्तव में कभी भी ट्रांजिस्टर का उपयोग नहीं किया है, लेकिन वे इस तरह सुपर काम करते हैं। – mange

0
(let [sidx (set idx)] 
    (vec      ;(sidx i) 
    (map-indexed (fn [i x] (if (contains? sidx i) (myfn x) x)) v))) 
+0

बहुत धीमी है। – BLUEPIXY

संबंधित मुद्दे