क्लोजर में, मुझे एक सूची में एक वेक्टर का उपयोग कब करना चाहिए, और दूसरे तरीके से?


147

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


जवाबों:


112

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

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

[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

जब आप फ़्रीनोड पर हों, तो डार्क साइड पर आएं और #stackoverflow में शामिल हों! :-P
क्रिस जस्टर-यंग

मैं वास्तव में वहाँ बेकार था। मैंने IRC क्लाइंट्स को स्विच किया और कभी भी अपने ऑटोजेन सूची में #stackoverflow को जोड़ने के बारे में नहीं सोचा।
रेने

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

23
यह पूरी तरह से अनचाही चैट स्निपेट है। "जनरेटिंग कोड" "बैक-टू-फ्रंट जेनरेट करता है" -> ठीक मतलब है ?? मुझे इस सवाल से वास्तव में कठिनाई हो रही है क्योंकि मेरी पुस्तक में आलस्य + घोषणात्मक शैली = बेहतर प्रदर्शन, और फिर भी क्लोज़र में हर जगह वैक्टर का सुझाव दिया गया है जो मुझे पूरी तरह से भ्रमित करता है।
जिमी होफा

22
@JimmyHoffa जिस तरह से मैं इसे समझता हूं: "जनरेटिंग कोड" = "इनसाइड ए मैक्रो" (क्योंकि अधिकांश कोड फ़ंक्शन कॉल है, इस प्रकार सूची); "फ्रंट टू बैक जनरेट करना" = "एक क्रम बनाकर प्रस्तुत करना"।
omiel

87

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

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

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

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)

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

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

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

पहले और अंतिम को जोड़ने के मामले में एक लिंक एक लिंक्ड सूची से बेहतर है। LLs बहुत भयानक हैं: P
बॉक्सिंग

1
@ बॉक्सिंग आप किसी वेक्टर के ऊपर या ArrayListबिना, प्रभावी ढंग से, ArrayDequeअपने आप को कार्यान्वित करते हुए एक डीके को लागू नहीं कर सकते ।
क्रिस जस्टर-यंग

43

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


3
तकनीकी रूप से, लिंक की गई सूचियों में O (1) एक्सेस समय है ... यदि आप केवल फ्रंट या बैक एलिमेंट एक्सेस कर रहे हैं। :-P हालाँकि, वैक्टर में O (1) यादृच्छिक अभिगम होता है। :-)
क्रिस जस्टर-यंग

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

1
जैसा कि कोई सिर्फ क्लीजुर में गोता लगा रहा है, यह अधिक वोटों के साथ अन्य दो की तुलना में बेहतर जवाब है। अन्य दो मुझे कुछ भी उपयोग नहीं बताते हैं।
कीथजग्रंट

@ क्रिसजेस्टर-यंग सिंगल-लिस्टेड लिस्ट में ओ (1) एक्सेस को सपोर्ट कर सकता है, अगर यह बैक एलिमेंट को रेफरेंस स्टोर करता है, जैसे
गिल बेट्स

30

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

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

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

  • जब आप इसे एक अनुक्रम के रूप में एक्सेस करना चाहते हैं (चूंकि नई वस्तुओं को आवंटित करने के बिना सूचियां सीधे समर्थन का समर्थन करती हैं)
  • Prepending - एक सूची की शुरुआत में विपक्ष या अधिमानतः संयोजन के साथ जोड़ना O (1) है

3
यहां तक ​​कि जब दोनों छोरों को जोड़ना / हटाना एक बहुत ही भयानक विकल्प है। एक डॉक बहुत बेहतर है (सीपीयू और विशेष रूप से मेमोरी में)। कोशिश करें github.com/pjstadig/deque-clojure
बॉक्सिंग

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

13

बस एक त्वरित पक्ष नोट:

"मैंने पढ़ा है कि वैक्टर seqs नहीं हैं, लेकिन सूचियाँ हैं।" 

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

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

Sec का एक शॉर्टकट है जो अपना तर्क देता है यदि वह पहले से ही seq है:

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);
}

सूचियां अनुक्रम हैं, हालांकि अन्य चीजें भी हैं, और सभी अनुक्रम सूची नहीं हैं।


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

2
क्या आपको classइसके बजाय मतलब नहीं है class??
qerub

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

मैंने वास्तव में किया था! मैं ठीक करूँगा कि
आर्थर उल्फेल्ट

अभी भी एक उलझन उलझन में है; चूँकि classआपके द्वारा बताए गए इन दोनों ही भावों के लिए समान PersistentList देता है, इसका मतलब है कि अनुक्रम और सूचियां वास्तव में एक ही बात हैं?
जॉन्बेकर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.