clojure
संग्रह और अनुक्रम
खोज…
वाक्य - विन्यास
-
'()→() -
'(1 2 3 4 5)→(1 2 3 4 5) -
'(1 foo 2 bar 3)→(1 'foo 2 'bar 3) -
(list1 2 3 4 5)→(1 2 3 4 5) -
(list*[1 2 3 4 5])→(1 2 3 4 5) -
[]→[] -
[1 2 3 4 5]→[1 2 3 4 5] -
(vector1 2 3 4 5)→[1 2 3 4 5] -
(vec'(1 2 3 4 5))→[1 2 3 4 5] -
{}=>{} -
{:keyA 1 :keyB 2}→ →{:keyA 1 :keyB 2} -
{:keyA 1, :keyB 2}→{:keyA 1 :keyB 2} -
(hash-map:keyA 1 :keyB 2)→{:keyA 1 :keyB 2} -
(sorted-map5 "five" 1 "one")→{1 "one" 5 "five"}(प्रविष्टियों कुंजी के द्वारा हल कर रहे हैं जब एक दृश्य के रूप में इस्तेमाल) -
#{}→#{} -
#{1 2 3 4 5}→#{4 3 2 5 1}(अनियंत्रित) -
(hash-set1 2 3 4 5)→#{2 5 4 1 3}(अव्यवस्थित) -
(sorted-set2 5 4 3 1)→#{1 2 3 4 5}
संग्रह
सभी बिल्ट-इन क्लोजर संग्रह अपरिवर्तनीय और विषम हैं, शाब्दिक वाक्यविन्यास हैं, और conj , count और seq फ़ंक्शन का समर्थन करते हैं।
-
conjएक नया संग्रह लौटाता है, जो कि "निरंतर" या "लघुगणक" समय में "जोड़े गए" आइटम के साथ मौजूदा संग्रह के बराबर है। वास्तव में इसका क्या मतलब संग्रह पर निर्भर करता है। - निरंतर समय में, संग्रह में वस्तुओं की संख्या की
countकरता है। -
seqरिटर्नnilएक खाली संग्रह, या एक गैर खाली संग्रह के लिए मदों की एक अनुक्रम, निरंतर समय में के लिए।
सूचियाँ
एक सूची कोष्ठकों द्वारा निरूपित किया जाता है:
()
;;=> ()
क्लोजर सूची एक एकल लिंक की गई सूची है । conj "conjoins" सबसे कारगर स्थान में संग्रह करने के लिए एक नए तत्व। सूचियों के लिए, यह शुरुआत में है:
(conj () :foo)
;;=> (:foo)
(conj (conj () :bar) :foo)
;;=> (:foo :bar)
अन्य संग्रहों के विपरीत, गैर-खाली सूचियों का मूल्यांकन विशेष रूपों, मैक्रो या कार्यों के मूल्यांकन के रूप में किया जाता है। इसलिए, जबकि (:foo) युक्त सूची का शाब्दिक प्रतिनिधित्व है :foo इसके केवल आइटम के रूप में, मूल्यांकन (:foo) एक आरईपीएल में एक कारण होगा IllegalArgumentException फेंक दिया, क्योंकि यदि किसी कीवर्ड का रूप लागू नहीं किया जा सकता nullary समारोह ।
(:foo)
;; java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :foo
क्लोजर को गैर-रिक्त सूची के मूल्यांकन से रोकने के लिए, आप इसे quote कर सकते हैं:
'(:foo)
;;=> (:foo)
'(:foo :bar)
;;=> (:foo :bar)
दुर्भाग्य से, इसका कारण तत्वों का मूल्यांकन नहीं किया जाना है:
(+ 1 1)
;;=> 2
'(1 (+ 1 1) 3)
;;=> (1 (+ 1 1) 3)
इस कारण से, आप आमतौर पर list का उपयोग करना चाहते हैं, एक चर समारोह जो इसके सभी तर्कों का मूल्यांकन करता है और उन परिणामों का उपयोग करता है:
(list)
;;=> ()
(list :foo)
;;=> (:foo)
(list :foo :bar)
;;=> (:foo :bar)
(list 1 (+ 1 1) 3)
;;=> (1 2 3)
निरंतर समय में वस्तुओं की संख्या की count :
(count ())
;;=> 0
(count (conj () :foo))
;;=> 1
(count '(:foo :bar))
;;=> 2
आप परीक्षण कर सकते हैं कि क्या कोई सूची का उपयोग करने वाली list? विधेय:
(list? ())
;;=> true
(list? '(:foo :bar))
;;=> true
(list? nil)
;;=> false
(list? 42)
;;=> false
(list? :foo)
;;=> false
आप का उपयोग करके सूची के पहले तत्व प्राप्त कर सकते हैं peek :
(peek ())
;;=> nil
(peek '(:foo))
;;=> :foo
(peek '(:foo :bar))
;;=> :foo
आप pop का उपयोग करते हुए पहले तत्व के बिना एक नई सूची प्राप्त कर सकते हैं:
(pop '(:foo))
;;=> ()
(pop '(:foo :bar))
;;=> (:bar)
ध्यान दें कि यदि आप एक खाली सूची को pop करने की कोशिश करते हैं, तो आपको एक IllegalStateException मिल जाएगी:
(pop ())
;; java.lang.IllegalStateException: Can't pop empty list
अंत में, सभी सूचियां अनुक्रम हैं, इसलिए आप एक सूची के साथ सब कुछ कर सकते हैं जो आप किसी अन्य अनुक्रम के साथ कर सकते हैं। वास्तव में, खाली सूची के अपवाद के साथ, एक सूची पर seq कॉल करना ठीक उसी वस्तु को लौटाता है:
(seq ())
;;=> nil
(seq '(:foo))
;;=> (:foo)
(seq '(:foo :bar))
;;=> (:foo :bar)
(let [x '(:foo :bar)]
(identical? x (seq x)))
;;=> true
दृश्यों
एक अनुक्रम एक सूची की तरह बहुत अधिक है: यह एक अपरिवर्तनीय वस्तु है जो आपको निरंतर समय में अपना first तत्व या इसके rest तत्व दे सकती है। आप यह भी कर सकते हैं cons एक मौजूदा अनुक्रम से एक नया अनुक्रम और शुरुआत में छड़ी के लिए एक आइटम truct।
आप परीक्षण कर सकते हैं कि क्या seq? उपयोग से कुछ अनुक्रम है seq? विधेय:
(seq? nil)
;;=> false
(seq? 42)
;;=> false
(seq? :foo)
;;=> false
जैसा कि आप पहले से ही जानते हैं, सूचियाँ अनुक्रम हैं:
(seq? ())
;;=> true
(seq? '(:foo :bar))
;;=> true
कुछ भी आप को फोन करके प्राप्त seq या rseq या keys या vals एक गैर खाली संग्रह पर भी एक अनुक्रम है:
(seq? (seq ()))
;;=> false
(seq? (seq '(:foo :bar)))
;;=> true
(seq? (seq []))
;;=> false
(seq? (seq [:foo :bar]))
;;=> true
(seq? (rseq []))
;;=> false
(seq? (rseq [:foo :bar]))
;;=> true
(seq? (seq {}))
;;=> false
(seq? (seq {:foo :bar :baz :qux}))
;;=> true
(seq? (keys {}))
;;=> false
(seq? (keys {:foo :bar :baz :qux}))
;;=> true
(seq? (vals {}))
;;=> false
(seq? (vals {:foo :bar :baz :qux}))
;;=> true
(seq? (seq #{}))
;;=> false
(seq? (seq #{:foo :bar}))
;;=> true
याद रखें कि सभी सूचियाँ अनुक्रम हैं, लेकिन सभी अनुक्रम सूची नहीं हैं। जबकि सूचियाँ समर्थन को peek और pop और निरंतर समय में count , सामान्य तौर पर, एक अनुक्रम को उन कार्यों में से किसी का समर्थन करने की आवश्यकता नहीं होती है। यदि आप एक ऐसे क्रम में peek या pop को कॉल करने का प्रयास करते हैं जो क्लोज़र के स्टैक इंटरफेस का समर्थन नहीं करता है, तो आपको ClassCastException मिलेगा:
(peek (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack
(pop (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack
(peek (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack
(pop (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack
(peek (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack
(pop (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack
यदि आप एक ऐसे क्रम पर count कहते हैं जो निरंतर समय में count को लागू नहीं करता है, तो आपको एक त्रुटि नहीं मिलेगी; इसके बजाय, क्लोजर पूरे अनुक्रम को पीछे ले जाएगा जब तक कि यह अंत तक नहीं पहुंचता है, फिर उन तत्वों की संख्या लौटाएं जो इसे ट्रैवर्स करते हैं। इसका मतलब है कि, सामान्य अनुक्रमों के लिए, count रैखिक है, निरंतर नहीं, समय। आप परीक्षण कर सकते हैं कि क्या कुछ counted? - count का उपयोग करके निरंतर-समय count का समर्थन करता है counted? विधेय:
(counted? '(:foo :bar))
;;=> true
(counted? (seq '(:foo :bar)))
;;=> true
(counted? [:foo :bar])
;;=> true
(counted? (seq [:foo :bar]))
;;=> true
(counted? {:foo :bar :baz :qux})
;;=> true
(counted? (seq {:foo :bar :baz :qux}))
;;=> true
(counted? #{:foo :bar})
;;=> true
(counted? (seq #{:foo :bar}))
;;=> false
जैसा कि ऊपर उल्लेख है, तो आप उपयोग कर सकते हैं first एक दृश्य के पहले तत्व प्राप्त करने के लिए। ध्यान दें कि first seq को उनके तर्क पर कॉल किया जाएगा, इसलिए इसका उपयोग "वास्तविक" कुछ भी हो सकता है, न कि केवल वास्तविक अनुक्रम:
(first nil)
;;=> nil
(first '(:foo))
;;=> :foo
(first '(:foo :bar))
;;=> :foo
(first [:foo])
;;=> :foo
(first [:foo :bar])
;;=> :foo
(first {:foo :bar})
;;=> [:foo :bar]
(first #{:foo})
;;=> :foo
जैसा कि ऊपर उल्लेख किया गया है, आप rest सभी का उपयोग कर सकते हैं, जिसमें एक मौजूदा अनुक्रम का पहला तत्व है। first तरह, यह अपने तर्क पर seq कहता है। हालांकि, यह अपने परिणाम पर seq नहीं कहता है! इसका मतलब यह है कि, यदि आप एक ऐसे क्रम में rest करते हैं जिसमें दो से कम आइटम हैं, तो आप nil बजाय वापस आ जाएंगे () :
(rest nil)
;;=> ()
(rest '(:foo))
;;=> ()
(rest '(:foo :bar))
;;=> (:bar)
(rest [:foo])
;;=> ()
(rest [:foo :bar])
;;=> (:bar)
(rest {:foo :bar})
;;=> ()
(rest #{:foo})
;;=> ()
तुम वापस प्राप्त करना चाहते हैं nil है जब वहाँ एक दृश्य में किसी भी अधिक तत्वों नहीं हैं, आप उपयोग कर सकते हैं next बजाय rest :
(next nil)
;;=> nil
(next '(:foo))
;;=> nil
(next [:foo])
;;=> nil
आप उपयोग कर सकते हैं cons एक नया अनुक्रम कि के लिए अपनी पहली तर्क वापस आ जाएगी बनाने के लिए समारोह first और के लिए अपने दूसरे तर्क rest :
(cons :foo nil)
;;=> (:foo)
(cons :foo (cons :bar nil))
;;=> (:foo :bar)
क्लूजुर अनुक्रमों से निपटने के लिए कई कार्यों के साथ एक बड़ा अनुक्रम पुस्तकालय प्रदान करता है। इस पुस्तकालय के बारे में महत्वपूर्ण बात यह है कि यह केवल सूचियों के साथ "seqable" कुछ भी काम करता है। इसलिए एक अनुक्रम की अवधारणा इतनी उपयोगी है; इसका मतलब है कि एक भी फ़ंक्शन, जैसे reduce , किसी भी संग्रह पर पूरी तरह से काम करता है:
(reduce + '(1 2 3))
;;=> 6
(reduce + [1 2 3])
;;=> 6
(reduce + #{1 2 3})
;;=> 6
अनुक्रम के उपयोगी होने का दूसरा कारण यह है कि, चूंकि वे first और rest किसी विशेष कार्यान्वयन को अनिवार्य नहीं करते हैं, वे आलसी दृश्यों की अनुमति देते हैं जिनके तत्वों को केवल तभी महसूस किया जाता है जब आवश्यक हो।
एक ऐसी अभिव्यक्ति को देखते हुए जो एक अनुक्रम बनाएगी, आप उस अभिव्यक्ति को lazy-seq मैक्रो में एक वस्तु प्राप्त करने के लिए लपेट सकते हैं जो अनुक्रम की तरह काम करता है, लेकिन वास्तव में उस अभिव्यक्ति का मूल्यांकन करेगा जब इसे seq फ़ंक्शन द्वारा ऐसा करने के लिए कहा जाता है, कौन सा बिंदु यह अभिव्यक्ति के परिणाम को कैश करेगा और first कैश्ड परिणाम के लिए कॉल को rest करेगा।
परिमित दृश्यों के लिए, एक आलसी अनुक्रम आमतौर पर एक समान उत्सुक अनुक्रम के समान कार्य करता है:
(seq [:foo :bar])
;;=> (:foo :bar)
(lazy-seq [:foo :bar])
;;=> (:foo :bar)
हालाँकि, अंतर अनंत दृश्यों के लिए स्पष्ट हो जाता है:
(defn eager-fibonacci [a b]
(cons a (eager-fibonacci b (+' a b))))
(defn lazy-fibonacci [a b]
(lazy-seq (cons a (lazy-fibonacci b (+' a b)))))
(take 10 (eager-fibonacci 0 1))
;; java.lang.StackOverflowError:
(take 10 (lazy-fibonacci 0 1))
;;=> (0 1 1 2 3 5 8 13 21 34)
वैक्टर
एक वेक्टर को वर्ग कोष्ठक द्वारा निरूपित किया जाता है:
[]
;;=> []
[:foo]
;;=> [:foo]
[:foo :bar]
;;=> [:foo :bar]
[1 (+ 1 1) 3]
;;=> [1 2 3]
शाब्दिक सिंटैक्स का उपयोग करने के अलावा, आप vector के निर्माण के लिए vector फ़ंक्शन का भी उपयोग कर सकते हैं:
(vector)
;;=> []
(vector :foo)
;;=> [:foo]
(vector :foo :bar)
;;=> [:foo :bar]
(vector 1 (+ 1 1) 3)
;;=> [1 2 3]
आप परीक्षण कर सकते हैं कि क्या कोई वेक्टर का उपयोग करके vector? विधेय:
(vector? [])
;;=> true
(vector? [:foo :bar])
;;=> true
(vector? nil)
;;=> false
(vector? 42)
;;=> false
(vector? :foo)
;;=> false
एक वेक्टर के अंत में conj तत्व जोड़ता है:
(conj [] :foo)
;;=> [:foo]
(conj (conj [] :foo) :bar)
;;=> [:foo :bar]
(conj [] :foo :bar)
;;=> [:foo :bar]
निरंतर समय में वस्तुओं की संख्या की count :
(count [])
;;=> 0
(count (conj [] :foo))
;;=> 1
(count [:foo :bar])
;;=> 2
आप एक सदिश का उपयोग करने का अंतिम तत्व प्राप्त कर सकते हैं peek :
(peek [])
;;=> nil
(peek [:foo])
;;=> :foo
(peek [:foo :bar])
;;=> :bar
आप pop का उपयोग कर अंतिम तत्व के बिना एक नया वेक्टर प्राप्त कर सकते हैं:
(pop [:foo])
;;=> []
(pop [:foo :bar])
;;=> [:foo]
ध्यान दें कि यदि आप एक खाली वेक्टर को पॉप करने की कोशिश करते हैं, तो आपको एक IllegalStateException मिलेगी:
(pop [])
;; java.lang.IllegalStateException: Can't pop empty vector
सूचियों के विपरीत, वैक्टर को अनुक्रमित किया जाता है। आप "निरंतर" समय में सूचकांक द्वारा वेक्टर का एक तत्व प्राप्त कर सकते get :
(get [:foo :bar] 0)
;;=> :foo
(get [:foo :bar] 1)
;;=> :bar
(get [:foo :bar] -1)
;;=> nil
(get [:foo :bar] 2)
;;=> nil
इसके अलावा, वैक्टर स्वयं ऐसे कार्य हैं जो एक सूचकांक लेते हैं और उस सूचकांक में तत्व को वापस करते हैं:
([:foo :bar] 0)
;;=> :foo
([:foo :bar] 1)
;;=> :bar
हालाँकि, यदि आप एक वेक्टर को अवैध सूचकांक कहते हैं, तो आपको nil बजाय एक IndexOutOfBoundsException मिलेगा:
([:foo :bar] -1)
;; java.lang.IndexOutOfBoundsException:
([:foo :bar] 2)
;; java.lang.IndexOutOfBoundsException:
आप का उपयोग कर एक विशेष सूचकांक पर एक अलग मूल्य के साथ एक नया वेक्टर प्राप्त कर सकते हैं assoc :
(assoc [:foo :bar] 0 42)
;;=> [42 :bar]
(assoc [:foo :bar] 1 42)
;;=> [:foo 42]
यदि आप वेक्टर की count के बराबर एक सूचकांक पास करते हैं, तो क्लीजुर तत्व को जोड़ देगा जैसे कि आपने conj का उपयोग किया था। हालाँकि, यदि आप एक इंडेक्स पास करते हैं जो कि ऋणात्मक या count से अधिक है, तो आपको एक IndexOutOfBoundsException :
(assoc [:foo :bar] 2 42)
;;=> [:foo :bar 42]
(assoc [:foo :bar] -1 42)
;; java.lang.IndexOutOfBoundsException:
(assoc [:foo :bar] 3 42)
;; java.lang.IndexOutOfBoundsException:
आप seq का उपयोग करके वेक्टर में आइटम का एक क्रम प्राप्त कर सकते हैं:
(seq [])
;;=> nil
(seq [:foo])
;;=> (:foo)
(seq [:foo :bar])
;;=> (:foo :bar)
चूंकि वैक्टर को अनुक्रमित किया जाता है, आप rseq का उपयोग करके वेक्टर की वस्तुओं का एक उल्टा क्रम भी प्राप्त कर सकते हैं:
(rseq [])
;;=> nil
(rseq [:foo])
;;=> (:foo)
(rseq [:foo :bar])
;;=> (:bar :foo)
ध्यान दें कि, हालांकि सभी सूचियाँ अनुक्रम हैं, और अनुक्रमों को सूचियों के समान प्रदर्शित किया जाता है, न कि सभी अनुक्रम सूचियाँ हैं!
'(:foo :bar)
;;=> (:foo :bar)
(seq [:foo :bar])
;;=> (:foo :bar)
(list? '(:foo :bar))
;;=> true
(list? (seq [:foo :bar]))
;;=> false
(list? (rseq [:foo :bar]))
;;=> false
सेट
नक्शे की तरह, सेट साहचर्य और अव्यवस्थित हैं। मानचित्रों के विपरीत, जिसमें कुंजियों से मानों तक मैपिंग होती है, अनिवार्य रूप से मानचित्रों को कुंजी से स्वयं में सेट करते हैं।
एक सेट को एक ऑक्टोथोरपे से पहले घुंघराले ब्रेसिज़ द्वारा दर्शाया गया है:
#{}
;;=> #{}
#{:foo}
;;=> #{:foo}
#{:foo :bar}
;;=> #{:bar :foo}
नक्शे के अनुसार, शाब्दिक सेट में तत्व दिखाई देने वाले क्रम में कोई फर्क नहीं पड़ता:
(= #{:foo :bar} #{:bar :foo})
;;=> true
आप परीक्षण कर सकते हैं कि क्या सेट के उपयोग से कुछ set? विधेय:
(set? #{})
;;=> true
(set? #{:foo})
;;=> true
(set? #{:foo :bar})
;;=> true
(set? nil)
;;=> false
(set? 42)
;;=> false
(set? :foo)
;;=> false
आप परीक्षण कर सकते हैं कि क्या मानचित्र में "निरंतर" समय में दिए गए आइटम में contains? विधेय:
(contains? #{} :foo)
;;=> false
(contains? #{:foo} :foo)
;;=> true
(contains? #{:foo} :bar)
;;=> false
(contains? #{} nil)
;;=> false
(contains? #{nil} nil)
;;=> true
इसके अलावा, सेट खुद ऐसे कार्य हैं जो एक तत्व लेते हैं और उस तत्व को वापस लौटाते हैं यदि यह सेट में मौजूद है, या नहीं तो nil है:
(#{} :foo)
;;=> nil
(#{:foo} :foo)
;;=> :foo
(#{:foo} :bar)
;;=> nil
(#{} nil)
;;=> nil
(#{nil} nil)
;;=> nil
आप एक सेट पाने के लिए conj का उपयोग कर सकते हैं जिसमें मौजूदा सेट के सभी तत्व हैं, साथ ही एक अतिरिक्त आइटम:
(conj #{} :foo)
;;=> #{:foo}
(conj (conj #{} :foo) :bar)
;;=> #{:bar :foo}
(conj #{:foo} :foo)
;;=> #{:foo}
आप किसी ऐसे सेट को प्राप्त करने के लिए disj का उपयोग कर सकते हैं disj एक मौजूदा सेट के सभी तत्व हैं, एक आइटम माइनस:
(disj #{} :foo)
;;=> #{}
(disj #{:foo} :foo)
;;=> #{}
(disj #{:foo} :bar)
;;=> #{:foo}
(disj #{:foo :bar} :foo)
;;=> #{:bar}
(disj #{:foo :bar} :bar)
;;=> #{:foo}
निरंतर समय में, तत्वों की संख्या की count :
(count #{})
;;=> 0
(count (conj #{} :foo))
;;=> 1
(count #{:foo :bar})
;;=> 2
आप seq का उपयोग करके एक सेट में सभी तत्वों का एक क्रम प्राप्त कर सकते हैं:
(seq #{})
;;=> nil
(seq #{:foo})
;;=> (:foo)
(seq #{:foo :bar})
;;=> (:bar :foo)
मैप्स
सूची के विपरीत, जो एक अनुक्रमिक डेटा संरचना है, और वेक्टर, जो अनुक्रमिक और साहचर्य दोनों है, मानचित्र विशेष रूप से एक साहचर्य डेटा संरचना है। मानचित्र में कुंजियों से मानों तक मैपिंग का एक सेट होता है। सभी कुंजियाँ अद्वितीय हैं, इसलिए मानचित्र कुंजियों से मूल्यों तक "निरंतर" -टाइम लुकअप का समर्थन करते हैं।
एक नक्शा घुंघराले ब्रेसिज़ द्वारा दर्शाया गया है:
{}
;;=> {}
{:foo :bar}
;;=> {:foo :bar}
{:foo :bar :baz :qux}
;;=> {:foo :bar, :baz :qux}
दो तत्वों की प्रत्येक जोड़ी एक कुंजी-मूल्य जोड़ी है। उदाहरण के लिए, ऊपर दिए गए पहले नक्शे में कोई मैपिंग नहीं है। दूसरे में एक मैपिंग है, कुंजी से :foo से मान :bar । तीसरे में दो मैपिंग हैं, एक कुंजी से :foo से मान :bar , और एक कुंजी से :baz से मान :qux । मानचित्र स्वाभाविक रूप से अनियंत्रित होते हैं, इसलिए मैपिंग के क्रम में कोई फर्क नहीं पड़ता:
(= {:foo :bar :baz :qux}
{:baz :qux :foo :bar})
;;=> true
आप परीक्षण कर सकते हैं कि क्या कोई मानचित्र का उपयोग करने वाला map? विधेय:
(map? {})
;;=> true
(map? {:foo :bar})
;;=> true
(map? {:foo :bar :baz :qux})
;;=> true
(map? nil)
;;=> false
(map? 42)
;;=> false
(map? :foo)
;;=> false
आप परीक्षण कर सकते हैं कि क्या किसी मानचित्र में "निरंतर" समय में दी गई कुंजी contains? विधेय:
(contains? {:foo :bar :baz :qux} 42)
;;=> false
(contains? {:foo :bar :baz :qux} :foo)
;;=> true
(contains? {:foo :bar :baz :qux} :bar)
;;=> false
(contains? {:foo :bar :baz :qux} :baz)
;;=> true
(contains? {:foo :bar :baz :qux} :qux)
;;=> false
(contains? {:foo nil} :foo)
;;=> true
(contains? {:foo nil} :bar)
;;=> false
तुम एक कुंजी का उपयोग कर के साथ जुड़े मूल्य प्राप्त कर सकते get :
(get {:foo :bar :baz :qux} 42)
;;=> nil
(get {:foo :bar :baz :qux} :foo)
;;=> :bar
(get {:foo :bar :baz :qux} :bar)
;;=> nil
(get {:foo :bar :baz :qux} :baz)
;;=> :qux
(get {:foo :bar :baz :qux} :qux)
;;=> nil
(get {:foo nil} :foo)
;;=> nil
(get {:foo nil} :bar)
;;=> nil
इसके अलावा, नक्शे स्वयं एक कार्य हैं जो एक कुंजी लेते हैं और उस कुंजी से जुड़े मूल्य को वापस करते हैं:
({:foo :bar :baz :qux} 42)
;;=> nil
({:foo :bar :baz :qux} :foo)
;;=> :bar
({:foo :bar :baz :qux} :bar)
;;=> nil
({:foo :bar :baz :qux} :baz)
;;=> :qux
({:foo :bar :baz :qux} :qux)
;;=> nil
({:foo nil} :foo)
;;=> nil
({:foo nil} :bar)
;;=> nil
आप एक दो-तत्व वेक्टर के रूप में संपूर्ण मानचित्र प्रविष्टि (कुंजी और मान एक साथ) find :
(find {:foo :bar :baz :qux} 42)
;;=> nil
(find {:foo :bar :baz :qux} :foo)
;;=> [:foo :bar]
(find {:foo :bar :baz :qux} :bar)
;;=> nil
(find {:foo :bar :baz :qux} :baz)
;;=> [:baz :qux]
(find {:foo :bar :baz :qux} :qux)
;;=> nil
(find {:foo nil} :foo)
;;=> [:foo nil]
(find {:foo nil} :bar)
;;=> nil
आप क्रमशः key या val का उपयोग करके मानचित्र प्रविष्टि से कुंजी या मान निकाल सकते हैं:
(key (find {:foo :bar} :foo))
;;=> :foo
(val (find {:foo :bar} :foo))
;;=> :bar
ध्यान दें कि, हालाँकि सभी Clojure मैप एंट्रीज वैक्टर हैं, सभी वैक्टर मैप एंट्रीज़ नहीं हैं। यदि आप किसी ऐसी चीज़ पर key या val को कॉल करने का प्रयास करते हैं जो मानचित्र प्रविष्टि नहीं है, तो आपको ClassCastException मिलेगा:
(key [:foo :bar])
;; java.lang.ClassCastException:
(val [:foo :bar])
;; java.lang.ClassCastException:
आप परीक्षण कर सकते हैं कि क्या map-entry? का उपयोग करके कोई map-entry? विधेय:
(map-entry? (find {:foo :bar} :foo))
;;=> true
(map-entry? [:foo :bar])
;;=> false
आप एक मानचित्र पाने के लिए assoc का उपयोग कर सकते हैं जिसमें मौजूदा मानचित्र के समान सभी मुख्य-मूल्य जोड़े हों, जिसमें एक मैपिंग जोड़ा या बदला गया हो:
(assoc {} :foo :bar)
;;=> {:foo :bar}
(assoc (assoc {} :foo :bar) :baz :qux)
;;=> {:foo :bar, :baz :qux}
(assoc {:baz :qux} :foo :bar)
;;=> {:baz :qux, :foo :bar}
(assoc {:foo :bar :baz :qux} :foo 42)
;;=> {:foo 42, :baz :qux}
(assoc {:foo :bar :baz :qux} :baz 42)
;;=> {:foo :bar, :baz 42}
आप किसी ऐसे मानचित्र को प्राप्त करने के लिए dissoc का उपयोग कर सकते हैं dissoc मौजूदा मानचित्र के समान सभी मुख्य-मूल्य जोड़े हों, संभवतः एक मैपिंग हटा दी गई हो:
(dissoc {:foo :bar :baz :qux} 42)
;;=> {:foo :bar :baz :qux}
(dissoc {:foo :bar :baz :qux} :foo)
;;=> {:baz :qux}
(dissoc {:foo :bar :baz :qux} :bar)
;;=> {:foo :bar :baz :qux}
(dissoc {:foo :bar :baz :qux} :baz)
;;=> {:foo :bar}
(dissoc {:foo :bar :baz :qux} :qux)
;;=> {:foo :bar :baz :qux}
(dissoc {:foo nil} :foo)
;;=> {}
निरंतर समय में मैपिंग की संख्या की count :
(count {})
;;=> 0
(count (assoc {} :foo :bar))
;;=> 1
(count {:foo :bar :baz :qux})
;;=> 2
आप seq का उपयोग कर नक्शे में सभी प्रविष्टियों का एक क्रम प्राप्त कर सकते हैं:
(seq {})
;;=> nil
(seq {:foo :bar})
;;=> ([:foo :bar])
(seq {:foo :bar :baz :qux})
;;=> ([:foo :bar] [:baz :qux])
फिर से, नक्शे अनियंत्रित होते हैं, इसलिए एक नक्शे पर seq कॉल करके प्राप्त होने वाले अनुक्रम में आइटम का क्रम अपरिभाषित होता है।
आप क्रमशः keys या vals का उपयोग करके मानचित्र में केवल कुंजियों या बस मानों का एक क्रम प्राप्त कर सकते हैं:
(keys {})
;;=> nil
(keys {:foo :bar})
;;=> (:foo)
(keys {:foo :bar :baz :qux})
;;=> (:foo :baz)
(vals {})
;;=> nil
(vals {:foo :bar})
;;=> (:bar)
(vals {:foo :bar :baz :qux})
;;=> (:bar :qux)
क्लोजर 1.9 एक मानचित्र के अधिक संक्षिप्त रूप से प्रतिनिधित्व करने के लिए एक शाब्दिक वाक्यविन्यास जोड़ता है जहां कुंजियाँ समान नाम स्थान साझा करती हैं। ध्यान दें कि या तो मामले में नक्शा समान है (मानचित्र डिफ़ॉल्ट नाम स्थान को "नहीं जानता" है), यह केवल एक सिंटैक्टिक सुविधा है।
;; typical map syntax
(def p {:person/first"Darth" :person/last "Vader" :person/email "[email protected]"})
;; namespace map literal syntax
(def p #:person{:first "Darth" :last "Vader" :email "[email protected]"})