मैं एक वेक्टर पर कैसे मैप कर सकता हूं और वेक्टर प्राप्त कर सकता हूं?


15

केवल एक चीज मैंने पाया है कि काम करता है

(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]

लेकिन ऐसा लगता है कि अब तक भी 'सही' रास्ता जटिल।

जवाबों:


19

cl-mapइसके बजाय, उपयोग करें :

(cl-map 'vector #'1+ [1 2 3 4])

एक छोटी सी अतिरिक्त पृष्ठभूमि: cl-mapहै कॉमन लिस्प mapसमारोह है कि अनुक्रम प्रकार को सामान्यीकृत:

(cl-map 'vector #'1+ '[1 2 3 4]) ;; ==> [2 3 4 5]
(cl-map 'list   #'1+ '(1 2 3 4)) ;; ==> (2 3 4 5)
(cl-map 'string #'upcase "abc")  ;; ==> "ABC"

यह अनुक्रम प्रकारों के बीच भी परिवर्तित हो सकता है (जैसे, यहाँ, इनपुट एक सूची है और आउटपुट एक वेक्टर है):

(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]

1
18 सेकंड 'विजेता' :) क्या clपुस्तकालय संकलक चेतावनी नहीं देते हैं, हालांकि? (अधिकतर क्योंकि FSF अप्रिय है?)
सीन एलेड

1
FWIW, मुझे लगता है कि बाइट संकलन समस्याएं पुराने clपुस्तकालय के बजाय पुराने पुस्तकालय से संबंधित थीं cl-lib। मैं उदाहरण के लिए नहीं, जब (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))और तब मुझे कोई चेतावनी मिलती है (byte-compile 'fnx)
दान

2
यहां तक ​​कि अगर आप संगतता सीएल-लिब का उपयोग करते हैं, तो मुझे लगता है कि आपको पुराने ईमैक्स (24.2) पर चेतावनी मिलेगी। मैं इसके बारे में चिंता नहीं करेगा, आपको अपनी लड़ाई चुननी होगी।
मालाबार

16

चूंकि मुझे 18 सेकंड से हराया गया था, इसलिए यहां सीएल लाइब्रेरी के बिना इसे करने का एक सरल और सुरक्षित तरीका है। यह तत्वों का मूल्यांकन भी नहीं करता है।

(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]

यह भी काफी अच्छा है! पुन: पुराने Emacs के बारे में आपकी पहले की टिप्पणी: यह विशेष रूप से उपयोगी लगता है यदि आपको विरासत उपयोगकर्ताओं का अनुमान लगाना है। यह सबसे ज्यादा मददगार लगता है अगर आपको इसे केवल एक-दो स्पॉट्स में इस्तेमाल करना है, तो इस बिंदु पर आप cl-libनिर्भरता से बचने के खिलाफ थोड़ी असुविधा से व्यापार कर सकते हैं ।
दान

1
बहुत निफ्टी !! मैं का उपयोग करने के बारे में नहीं सोचा था apply
सीन एलेड

मुझे लगता है (apply #'vector ...)कि यह कभी भी थोड़ा तेज हो सकता है, लेकिन पूर्णता के लिए, इसे भी बदला जा सकता है (vconcat ...)
तुलसी

1

इस मामले के लिए इतना सुरुचिपूर्ण इन-वेरिएंट नहीं है कि मूल वेक्टर की बाद में आवश्यकता नहीं है और मेमोरी आवंटन समय-महत्वपूर्ण है (जैसे वेक्टर बड़ा है)।

(setq x [1 2 3 4])

(cl-loop for var across-ref x do
         (setf var (1+ var)))

परिणाम में संग्रहीत किया जाता है x। यदि आपको xअंत में लौटने के लिए फॉर्म की आवश्यकता है, तो आप finally return xनिम्नानुसार जोड़ सकते हैं :

(cl-loop for var across-ref x do
         (setf var (1+ var))
         finally return x)

1

पूर्णता के लिए, उपयोग करते हुए seq:

(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)

सटीक लाइन के साथ Fólkvangr 2018-11-12 से हटाए गए उत्तर हैं seq-into। उपयोगकर्ता ने निम्नलिखित कारण के लिए अपना उत्तर हटा दिया है: "मेरा समाधान कम प्रासंगिक है क्योंकि seq पुस्तकालय अंतर्निहित कॉमन लिस्प एक्सटेंशन का उपयोग करता है। - Fólkvangr 16 मई को 8:53"
टोबियास

@ टोबियास मुझे लगता है कि मैं उस तर्क से असहमत हूं। सब कुछ वैसे भी vconcat या वेक्टर का उपयोग करने के लिए समाप्त होने जा रहा है, लेकिन विभिन्न इंटरफ़ेस प्रतिमान रिकॉर्ड पर उपयोगी होते हैं।
सीन एलेड

कोई दिक्कत नहीं है। मैंने अभी-अभी Fllkvangr (लगभग) के डिलीट किए गए उत्तर को आपका मिलान देखा और आपको सूचित करना चाहता था। जिस किसी कारण से हटाए गए उत्तरों को देखने के लिए 10000 प्रतिनिधि की आवश्यकता होती है :-(।
टोबीस

@ टोबिया हाँ, मैं वास्तव में कभी नहीं समझ पाया कि वे विशेषाधिकार साइट-विशेष :-) क्यों थे
सीन एलेड

0

आप लूप का उपयोग कर सकते हैं

(let ((v (vector 1 2 3 4)))
  (dotimes (i (length v))
    (aset v i (1+ (aref v i))))
  v)
;; => [2 3 4 5]

कभी-कभी आप मूल वेक्टर को संशोधित नहीं करना चाहते हैं, तो आप एक प्रतिलिपि बना सकते हैं

(let* ((v0 (vector 1 2 3 4))
       (v (copy-sequence v0)))
  (dotimes (i (length v))
    (aset v i (1+ (aref v i))))
  (list v0 v))
;; => ([1 2 3 4] [2 3 4 5])

या खरोंच से एक नया वेक्टर बनाएँ

(let* ((v0 (vector 1 2 3 4))
       (v (make-vector (length v0) nil)))
  (dotimes (i (length v))
    (aset v i (1+ (aref v0 i))))
  (list v0 v))
;; => ([1 2 3 4] [2 3 4 5])
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.