2009-07-18 11 views
128

मैंने पढ़ा कि वेक्टर seqs नहीं हैं, लेकिन सूचियां हैं। मुझे यकीन नहीं है कि दूसरे पर एक का उपयोग करने के लिए तर्क क्या है। ऐसा लगता है कि वैक्टर का सबसे अधिक उपयोग किया जाता है, लेकिन इसके लिए कोई कारण है?क्लोजर में, मुझे किसी सूची में वेक्टर का उपयोग कब करना चाहिए, और दूसरी तरफ?

+1

संबंधित http://stackoverflow.com/questions/6928327/when-should-i-choose-vector-in-scala –

उत्तर

99

एक बार फिर, ऐसा लगता है कि मैंने अधीर होने और फ्रीनोड पर #clojure में पूछकर अपने स्वयं के प्रश्न का उत्तर दिया है। Stackoverflow.com पर आपके अपने सवालों का जवाब देने वाली अच्छी बात को प्रोत्साहित किया जाता है: डी

मैंने रिच हिकी के साथ त्वरित चर्चा की, और यहां इसकी जानकारी है।

[12:21] <Raynes> Vectors aren't seqs, right? 
[12:21] <rhickey> Raynes: no, but they are sequential 
[12:21] <rhickey> ,(sequential? [1 2 3]) 
[12:21] <clojurebot> true 
[12:22] <Raynes> When would you want to use a list over a vector? 
[12:22] <rhickey> when generating code, when generating back-to-front 
[12:23] <rhickey> not too often in Clojure 
+0

जबकि आप फ्रीनोड पर हैं, अंधेरे तरफ आएं और # स्टैक ओवरफ्लो में शामिल हों! :- पी –

+0

मैं वास्तव में वहां निष्क्रिय करने के लिए प्रयोग किया जाता था। मैंने आईआरसी क्लाइंट्स को स्विच किया और कभी भी मेरी ऑटोजॉइन सूची में # स्टैक ओवरफ्लो जोड़ने का विचार नहीं किया। – Rayne

+0

मैं एक लिस्प नौसिखिया हूं, लेकिन मुझे आश्चर्य हुआ कि वैक्टर, मानचित्र और सेट किसी भी तरह से विचार करते हैं कि सभी कोड डेटा के साथ अंतर-परिवर्तनीय है? या क्या यह उन चीजों में से एक है जो क्लोजर को एक व्यावहारिक लिस्प बनाता है? (या, क्या आप एक वेक्टर का मूल्यांकन कर सकते हैं?) –

75

यदि आपने जावा प्रोग्रामिंग बहुत कुछ किया है, और जावा संग्रह ढांचे से परिचित हैं, तो LinkedList जैसे सूचियों और ArrayList जैसे वैक्टरों के बारे में सोचें। तो आप कंटेनर को वैसे ही चुन सकते हैं।

आगे स्पष्टीकरण के लिए: यदि आप अलग-अलग वस्तुओं को आगे या अनुक्रम के पीछे अलग-अलग जोड़ना चाहते हैं, तो एक लिंक्ड सूची वेक्टर की तुलना में काफी बेहतर है, क्योंकि वस्तुओं को हर बार चारों ओर घूमने की आवश्यकता नहीं होती है । हालांकि, यदि आप विशिष्ट तत्वों (सूची के सामने या पीछे के पास नहीं) अक्सर प्राप्त करना चाहते हैं (यानी, यादृच्छिक पहुंच), तो आप वेक्टर का उपयोग करना चाहेंगे।

वैसे, वैक्टर आसानी से seqs में बदल सकते हैं।

user=> (def v (vector 1 2 3)) 
#'user/v 
user=> v 
[1 2 3] 
user=> (seq v) 
(1 2 3) 
user=> (rseq v) 
(3 2 1) 
+0

वेक्टर seqs नहीं हैं लेकिन वे अनुक्रमिक हैं। (स्रोत: Freenode पर #clojure पर खुद को रिच।) इसके अलावा, मैं वास्तव में जावा बिल्कुल नहीं जानता, लेकिन रिच ने सिर्फ मेरे सवाल का जवाब दिया। – Rayne

+1

मैं अपनी पोस्ट को कहने के लिए संपादित करूंगा, वेक्टर फ़ंक्शन के माध्यम से वैक्टर को _made in_qqs में जोड़ा जा सकता है। :-) –

+2

अपना उत्तर चुनें क्योंकि उसने वास्तव में प्रश्न का उत्तर दिया था, और मैं वास्तव में अपने उत्तरों को सही के रूप में चुनना पसंद नहीं करता हूं। सही प्रतीत नहीं होता है। धन्यवाद। :) – Rayne

34

वेक्टरों में ओ (1) यादृच्छिक पहुंच के समय होते हैं, लेकिन उन्हें पहले से ही रोकना होगा। सूचियों को गतिशील रूप से बढ़ाया जा सकता है, लेकिन एक यादृच्छिक तत्व तक पहुंच ओ (एन) है।

+2

तकनीकी रूप से, लिंक्ड सूचियों में ओ (1) एक्सेस टाइम्स हैं ... यदि आप केवल सामने या पीछे तत्व तक पहुंच रहे हैं। :-P हालांकि, वैक्टरों में ओ (1) यादृच्छिक पहुंच होती है। :-) –

+4

(ऊपर वर्णित अनुसार "लिंक्ड सूची" दोगुनी-लिंक्ड सूचियों को संदर्भित करती है। सिंगल-लिंक्ड सूचियों में ओ (1) केवल फ्रंट तत्व तक पहुंच है। :-P) –

+0

संपादन करने के लिए धन्यवाद! :-) –

12

बस एक त्वरित पक्ष ध्यान दें:

"I read that Vectors are not seqs, but Lists are."

दृश्यों या तो सूची या वैक्टर (या नक्शे या सेट) की तुलना में अधिक सामान्य हैं।
यह दुर्भाग्यपूर्ण है कि REPL प्रिंट्स सूचीबद्ध करता है और उसी को अनुक्रमित करता है क्योंकि यह वास्तव में सूचियों की तरह दिखता है, भले ही वे अलग हैं। (seq) फ़ंक्शन सूचियों सहित कई अलग-अलग चीजों से अनुक्रम बनाएगा, और फिर आप उन सीकों को किसी भी प्रकार के कार्यों को खिला सकते हैं जो निफ्टी चीजों को seqs के साथ करते हैं। हालांकि अन्य बातों के साथ-साथ हैं, और नहीं सभी दृश्यों सूची नहीं है

user> (let [alist (list 1 2 3)] (identical? alist (seq alist))) 
true 
user> (identical? (list 1 2 3) (seq (list 1 2 3))) 
false 

static public ISeq seq(Object coll){ 
     if(coll instanceof ASeq) 
       return (ASeq) coll; 
     else if(coll instanceof LazySeq) 
       return ((LazySeq) coll).seq(); 
     else 
       return seqFrom(coll); 
} 

सूचियों, दृश्यों हैं:

user> (class (list 1 2 3)) 
clojure.lang.PersistentList 

user> (class (seq (list 1 2 3))) 
clojure.lang.PersistentList 

user> (class (seq [1 2 3])) 
clojure.lang.PersistentVector$ChunkedSeq 

सेक अगर यह पहले से ही एक seq है एक शॉर्टकट है कि इसके तर्क देता है।

+0

मुझे एक छोटे से बिंदु को चुनने का मतलब नहीं है, यह सिर्फ कुछ उपयोगी बात करने का अवसर है।कई पहले से ही यह जान लेंगे :) –

+2

क्या आपका मतलब 'कक्षा' के बजाय 'वर्ग' नहीं है? – qerub

+0

क्लोजर अपडेट (मुझे लगता है कि मैं 1.5 पर हूं) के बाद आपका उदाहरण बदल गया है, लेकिन आपके दोनों उदाहरण मेरे लिए 'clojure.lang.PersistentList' वापस लौटते हैं। मुझे लगता है कि आप 'कक्षा' नहीं 'वर्ग' लिखना चाहते हैं? –

24

एक वेक्टर उपयोग कब करें:

  • इंडेक्स्ड पहुँच प्रदर्शन - आप मिल ~ हे (1) सूचियों के लिए बनाम हे (एन) अनुक्रमित पहुँच के लिए लागत
  • जोड़कर - संयोजक के साथ है ~ ओ (1)
  • सुविधाजनक नोटेशन - मुझे परिस्थितियों में एक शाब्दिक सूची के लिए '1 1 3] की तुलना में [1 2 3] टाइप करना और पढ़ने के लिए दोनों आसान लगता है जहां या तो काम करेगा।

एक सूची उपयोग कब करें:

  • आप एक दृश्य के रूप में यह तक पहुँचने के लिए
  • prepending (सूचियों के बाद से सीधे नई वस्तुओं के आवंटन के लिए बिना seq समर्थन) चाहते हैं - के शुरू में जोड़ने विपक्ष या अधिमानतः संयोजक के साथ एक सूची है, हे (1)
+2

तब भी जब दोनों सिरों को जोड़ना/निकालना एक सूची एक बहुत ही भयानक पसंद है। एक डेक बहुत बेहतर है (सीपीयू और विशेष रूप से स्मृति में)। Https://github.com/pjstadig/deque-clojure – boxed

+1

पुन: '~ ओ (1) ', जिनके लिए यह लागत स्पष्टीकरण उपयोगी हो सकता है - http://stackoverflow.com/questions/200384/constant -amortized समय –

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