लज्जत में आलसी अनुक्रम को गैर आलसी में कैसे बदलें


95

मैंने क्लोजर में निम्नलिखित की कोशिश की, एक गैर-आलसी अनुक्रम के वर्ग की उम्मीद की वापसी की:

(.getClass (doall (take 3 (repeatedly rand))))

हालांकि, यह अभी भी लौटता है clojure.lang.LazySeq। मेरा अनुमान है कि doallयह पूरे अनुक्रम का मूल्यांकन करता है, लेकिन मूल अनुक्रम लौटाता है क्योंकि यह अभी भी संस्मरण के लिए उपयोगी है।

तो एक आलसी से गैर-आलसी अनुक्रम बनाने का मुहावरेदार साधन क्या है?


मुझे आश्चर्य है कि किसी ने भी यह नहीं पूछा कि आप वास्तविक प्रकार के रिटर्न मूल्य के बारे में चिंतित हैंdoall
tar

आप एक वेक्टर में बदल सकते हैं:(vec (take 3 (repeatedly rand)))
क्रिस

जवाबों:


161

doallआपको जो चाहिए वह यह है। सिर्फ इसलिए कि seqटाइप का LazySeqमतलब यह नहीं है कि इसका मूल्यांकन लंबित है। आलसी seqअपने परिणामों को कैश करते हैं, इसलिए आपको यह सब करने के लिए आलसी को seqएक बार (जैसा कि doallकरता है) चलना होगा , और इस तरह इसे गैर-आलसी के रूप में प्रस्तुत करना होगा। पूरे संग्रह का मूल्यांकन करने के लिए मजबूर नहींseq करता है ।


2
मैंने इसे स्वीकृत उत्तर में बदल दिया है। एक संबंधित नोट पर, आप किस माध्यम से यह निर्धारित कर सकते हैं कि एक लेज़ीसेक का पहले मूल्यांकन किया गया है?
टिम क्लेमन

10
मेरा मानना ​​है कि आप सिर्फ कॉल करें realized?
2

1
शायद realizeमैच के लिए एक ऑपरेशन होना चाहिए realized?
रीट शरबानी

यह सब बहुत अच्छा है। लेकिन कुछ कार्यों की तरह contains?आप परवाह नहीं करते हैं कि आपने आलसी seq को महसूस किया है या नहीं, यह विशिष्ट प्रश्न के उत्तर के रूप में पूछा गया है, लेकिन प्रश्न के शीर्षक के लिए कम है।
matanster

75

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

  • एक पूर्व आलसी (पूरी तरह से मूल्यांकन) आलसी अनुक्रम (doall ... )
  • अनुक्रमिक पहुंच के लिए एक सूची (apply list (my-lazy-seq)) OR (into () ...)
  • बाद में यादृच्छिक अभिगम के लिए एक वेक्टर (vec (my-lazy-seq))
  • एक नक्शा या एक सेट अगर आप कुछ विशेष उद्देश्य है।

आपके पास जो भी प्रकार का अनुक्रम हो वह आपकी आवश्यकताओं को पूरा करता है।


यह सबसे अच्छा जवाब है।
फेलिप

4
स्वीकृत उत्तर तकनीकी रूप से सही है, लेकिन यह उत्तर मेरे लिए सबसे उपयोगी था। मैं एक वेक्टर पर एक फ़ंक्शन को मैप करने की कोशिश कर रहा था और फिर एक फ़ाइल के लिए परिणाम थूक रहा था, और कॉल के बाद भी, कॉल में अनुक्रम की सामग्री के बजाय "clojure.lang.LazySeq@address" फ़ाइल थी। वैल्यू मैप पर वीसी बुलाने से मुझे वह मिल गया जो मुझे फ़ाइल से बाहर निकालने के लिए चाहिए था।
जेसी रोजालिया

1
@ जेसेरोसालिया यह जानना अच्छा है कि एसओ के सभी में केवल और केवल रिच हिकी की प्रतिक्रिया तकनीकी रूप से सही थी। ;-)
फिल कूपर

(vec (my-lazy-seq))निम्न जैसी स्थितियों में इतना अच्छा नहीं है: (vec (json/parse-string "{\"foo\":\"bar\"}")) ;; => [["foo" "bar"]]चूँकि cheshireएक आलसी- (json/parse-string)
सेक्

उपरोक्त के लिए (json/parse-string-strict)
बाध्यता

22

इस अमीर आदमी को उसका लहंगा मालूम होता है और बिलकुल सही है।
Buth मुझे लगता है कि यह कोड-स्निपेट, आपके उदाहरण का उपयोग करते हुए, इस प्रश्न का एक उपयोगी पूरक हो सकता है:

=> (realized? (take 3 (repeatedly rand))) 
false
=> (realized? (doall (take 3 (repeatedly rand)))) 
true

वास्तव में प्रकार नहीं बदला है, लेकिन एहसास हुआ है


2
यह ध्यान देने योग्य है, हालांकि, आपको पूरे अनुक्रम realized?को वापस लौटने के लिए मजबूर करने की आवश्यकता नहीं है true। जैसे(let [r (range) r? (realized? r)] (doall (take 1 r)) [r? (realized? r)]) => [false true]
एलेक्स कॉवेन्ट्री

22
यह अमीर आदमी: डी हाहा
निम्रोद

10
@nimrod :) सजा हालांकि "hís clojure" में होना था।
पीटर

10
जो लोग नहीं जानते हैं, उनके लिए "द रिच मैन" ने क्लजुरे का आविष्कार किया।
erturne

1
@AlexCoventry अपना उदाहरण देता है[true true]

7

मैं इस ब्लॉग पोस्ट पर doallपुनरावर्ती नहीं होने के बारे में ठोकर खाई । उसके लिए मुझे पोस्ट में पहला कमेंट मिला, ट्रिक। की तर्ज पर कुछ:

(use 'closure.walk)
(postwalk identity nested-lazy-thing)

मुझे यह एक यूनिट टेस्ट में उपयोगी लगा, जहां मैं कुछ नेस्टेड एप्लिकेशन के मूल्यांकन को mapएक त्रुटि स्थिति के लिए मजबूर करना चाहता था ।


5
(.getClass (into '() (take 3 (repeatedly rand))))

3
यह एक भयानक विचार है। यह इनपुट seq को उलट देता है।
अमलॉयल

3
बेशक, इस मामले में इनपुट को उलटने से कोई फर्क नहीं पड़ता है, क्योंकि वे सिर्फ 3 यादृच्छिक संख्याएँ हैं .... :-)
mikera
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.