clojure
संग्रह और अनुक्रम
खोज…
वाक्य - विन्यास
-
'()
→()
-
'(1 2 3 4 5)
→(1 2 3 4 5)
-
'(1 foo 2 bar 3)
→(1 'foo 2 'bar 3)
-
(
list
1 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]
-
(
vector
1 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-map
5 "five" 1 "one")
→{1 "one" 5 "five"}
(प्रविष्टियों कुंजी के द्वारा हल कर रहे हैं जब एक दृश्य के रूप में इस्तेमाल) -
#{}
→#{}
-
#{1 2 3 4 5}
→#{4 3 2 5 1}
(अनियंत्रित) -
(
hash-set
1 2 3 4 5)
→#{2 5 4 1 3}
(अव्यवस्थित) -
(
sorted-set
2 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]"})