क्लोजर में सूची प्रकारों के बीच परिवर्तित करने का एक आसान तरीका है?


92

मैं अक्सर अपने आप को एक आलसी सूची का उपयोग करते हुए पा रहा हूं जब मुझे एक वेक्टर चाहिए, और इसके विपरीत। इसके अलावा, कभी-कभी मेरे पास नक्शे का एक वेक्टर होता है, जब मैं वास्तव में नक्शे का एक सेट चाहता था। क्या इन प्रकारों के बीच बदलने में मेरी मदद करने के लिए कोई सहायक कार्य हैं?

जवाबों:


144

आइए यह मत भूलो कि भरोसेमंद पुराना intoआपको कुछ भी लेने में seqसक्षम बनाता है (सूची, वेक्टर, मानचित्र, सेट, सॉर्ट-मैप) और एक खाली कंटेनर जिसे आप भरना चाहते हैं, और इसे डालते intoहैं।

(into [] '(1 2 3 4)) ==> [1 2 3 4]         "have a lazy list and want a vector"
(into #{} [1 2 3 4]) ==> #{1 2 3 4}        "have a vector and want a set"
(into {} #{[1 2] [3 4]}) ==> {3 4, 1 2}    "have a set of vectors want a map"
(into #{} [{1 2} {3 4}]) ==> #{{1 2} {3 4}} "have a vector of maps want a set of maps"

intoचारों ओर एक आवरण है conj, जो संग्रह के प्रकार के आधार पर एक संग्रह में उचित रूप से नई प्रविष्टियां डालने के लिए आधार अमूर्त है। सिद्धांत यह है कि इस प्रवाह इतनी अच्छी तरह से करता है कि Clojure पर निर्माण है composable कपोल-कल्पना , इस मामले में intoकी चोटी पर conjसंग्रह के शीर्ष और पर seq

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


3
+1 के लिए ... ध्यान देने योग्य है कि यह गैर-खाली मूल कंटेनरों के साथ भी काम करता है (यानी जब आप एक संग्रह में जोड़ना चाहते हैं)
mikera

11
यह भी ध्यान देने योग्य है कि क्योंकि intoउपयोग करता है conj, ऐसा करने (into '() some-seq)से एक सूची प्राप्त होगी जो कुछ- सेक् का उल्टा है, क्योंकि conjसूचियों पर सहमति होती है।
चक

यह ध्यान देने योग्य है कि intoअधिकांश अन्य रूपांतरण साधनों की तुलना में बेहतर प्रदर्शन विशेषताओं के लिए (सबसे seq प्रकारों के लिए) ग्राहकों का उपयोग करता है।
जार्रेड हम्फ्रे

और अब यह ट्रांसड्यूसर्स के साथ काम करता है, जो उस समय मौजूद नहीं था जब यह उत्तर लिखा गया था (मुझे नहीं पता कि क्या या तो
मरीजों

33

vec, setऔर आम तौर intoपर आपके मित्र आसानी से दूसरे प्रकार के संग्रह में "कन्वर्ट" होते हैं।

आप नक्शे के वेक्टर को नक्शे के नक्शे में कैसे बदलना चाहते हैं? आपको एक कुंजी की आवश्यकता है, क्या आप नमूना इनपुट / अपेक्षित आउटपुट के साथ उपयोग प्रदान कर सकते हैं?


क्षमा करें, मेरा मतलब था नक्शों का एक सेट .. मैंने अब सवाल में संशोधन कर दिया है
appshare.co

22

वैक्टर के लिए vecफ़ंक्शन है

user=> (vec '(1 2 3))
[1 2 3]

आलसी दृश्यों के लिए lazy-seqकार्य है

user=> (lazy-seq [1 2 3])
(1 2 3)

सेट में परिवर्तित करने के लिए, setफ़ंक्शन है

user=> (set [{:a :b, :c :d} {:a :b} {:a :b}])
#{{:a :b} {:a :b, :c :d}}

4
जब आपके पास कुछ नॉन-लेजी कॉलिंग होती है, तो lazy-seqइसके बजाय seqएक बेकार अप्रत्यक्ष जोड़ देता है। अगर वास्तव में आप कुछ गैर-शून्य वापस करना चाहते हैं तो भी खाली सामूहिकता है sequencelazy-seqकुछ निम्न स्तर का निर्माण है।
11:30

14

सूची से नक्शे में बदलने के लिए एक और उत्तर (पूर्णता के लिए) - यहाँ से :

(apply hash-map '(1 2 3 4))
;=>{1 2, 3 4}

9

एक वेक्टर को एक सूची में बदलने के लिए आप forइस तरह का उपयोग कर सकते हैं :

=> (for [i [1 2 3 4]] i)
(1 2 3 4)

जब आप डेटा में हेरफेर नहीं करना चाहते हैं, तो बस seqवेक्टर पर उपयोग करें :

=> (seq [1 2 3])
(1 2 3)

इसके बजाय forआप बस कर सकते हैं(map identity [1 2 3 4])
सिल्टलाऊ

7

वेक्टर को सूची में बदलने की कोई आवश्यकता नहीं है । क्लोजर एक वेक्टर का इलाज करेगा क्योंकि यह एक सूची का इलाज करेगा - एक अनुक्रम के रूप में - जब एक अनुक्रम की आवश्यकता होती है। उदाहरण के लिए,

user=> (cons 0 [1 2 3])
(0 1 2 3)

यदि आपको यह सुनिश्चित करने की आवश्यकता है कि वेक्टर को अनुक्रम के रूप में माना जा रहा है, तो इसे इसमें लपेटें seq:

user=> (conj [1 2 3] 0) ; treated as a vector
[1 2 3 0]

user=> (conj (seq [1 2 3]) 0) ; treated as a sequence
(0 1 2 3)

यदि आपके पास नक्शे का वेक्टर है, और आप नक्शे का एक सेट चाहते हैं, तो इससे कोई फर्क नहीं पड़ता कि वेक्टर नक्शे रखता है। आप हमेशा की तरह वेक्टर को एक सेट में बदलते हैं:

user=> (set [{:a 1, :b 2} {"three" 3, "four" 4}])
#{{:a 1, :b 2} {"four" 4, "three" 3}}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.