2012-02-10 24 views
12

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

मैं इसे प्राप्त करने के लिए क्लोजर का उपयोग कर रहा हूं।

एक क्वेरी परिणाम एक कस्टम इटरेटर की तरह [1] ऑब्जेक्ट है, इसलिए क्लोजर seq बॉक्स से बाहर काम नहीं करता है।

कस्टम जावा इटरेटर को क्लोजर अनुक्रम में ऑब्जेक्ट की तरह बदलने का सबसे शानदार तरीका क्या है?

मेरे दिमाग में आने वाला सबसे स्पष्ट और गूंगा विचार यह है कि इस पर लूप करें और क्लोजर वेक्टर बनाएं, लेकिन मुझे यकीन है कि इस समस्या के लिए और अधिक सुरुचिपूर्ण दृष्टिकोण है।

[1] http://www.openrdf.org/doc/sesame2/api/info/aduna/iteration/Iteration.html

उत्तर

8

परीक्षण किया संस्करण:

(defn iteration->seq [iteration] 
(seq 
    (reify java.lang.Iterable 
     (iterator [this] 
     (reify java.util.Iterator 
      (hasNext [this] (.hasNext iteration)) 
      (next [this] (.next iteration)) 
      (remove [this] (.remove iteration))))))) 
+2

यह (इटरेटर के बजाय इटेरेबल को सुधारना) एक दृष्टिकोण है; दूसरा Iterator को दोबारा सुधारना है और फिर इसे ['iterator-seq'] (http://clojuredocs.org/clojure_core/clojure.core/iterator-seq) से लपेटना है। – amalloy

+0

अच्छा, जानना अच्छा है! – laczoka

5

कैसे एक वस्तु है कि वास्तव में Iterator इंटरफ़ेस लागू करता है में इटरेटर जैसी वस्तु लपेटकर के बारे में? निम्नलिखित (नहीं परीक्षण किया) की तरह कुछ:

(defn iteration-seq [iteration] 
    (iterator-seq 
    (reify java.util.Iterator 
    (hasNext [this] (.hasNext iteration)) 
    (next [this] (.next iteration)) 
    (remove [this] (.remove iteration))))) 

जहां तक ​​मेरा बता सकते हैं, केवल लाभ मानक Iterator इंटरफ़ेस पर Iteration इंटरफ़ेस का (यदि आप यह है कि यह कॉल करना चाहते हैं) है कि यह घोषणा करने के लिए अनुमति देता है चेक अपवाद, जिनका उपयोग क्लोजर में किसी भी तरह से नहीं किया जाता है।

[अद्यतन: सही कोड seq के बजाय iterator-seq उपयोग करने के लिए, के रूप में एक और उत्तर पर एक टिप्पणी में @amalloy ने सुझाव दिया।]

+0

धन्यवाद। काफी नहीं, लेकिन यह मुझे सही दिशा में इंगित किया और मुझे * reify * के व्यावहारिक उपयोग के बारे में जानने में मदद की। – laczoka

+0

मुझे पहले से ही एक परीक्षण सही संस्करण मिला है, कुछ प्रतिष्ठा प्रतिबंध के कारण अभी तक स्वयं का जवाब नहीं दे सकता है। :) – laczoka

1

शुद्ध कार्यात्मक iterable-हैं- जावा Iterable और इटरेटर

(defn iter-seq 
    ([iterable] 
    (iter-seq iterable (.iterator iterable))) 
    ([iterable i] 
    (lazy-seq 
     (when (.hasNext i) 
     (cons (.next i) (iter-seq iterable i)))))) 

के लिए आलसी-अनुक्रम कोड कस्टम iterators लिए .iterator, .hasNext और .next कॉल की जगह।

लाभ यह है कि यह पूरी तरह से कार्यात्मक है क्योंकि यह तर्क के रूप में पुन: प्रयोज्य होता है। अन्य पोस्ट किए गए समाधान इटेटरेटर तर्क लेते हैं जो उत्परिवर्तनीय है इसलिए फ़ंक्शन आंतरिक पुनरावर्तक स्थिति के आधार पर एक अलग अनुक्रम लौटा सकता है जो referential transparency का उल्लंघन करता है। फ़ंक्शन भी इसकी आलस्य के बारे में शानदार है।

1

clojure.core/iterator-seq क्यों नहीं आज़माएं?

user=> (doc iterator-seq) 
------------------------- 
clojure.core/iterator-seq 
([iter]) 
    Returns a seq on a java.util.Iterator. Note that most collections 
    providing iterators implement Iterable and thus support seq directly. 

आप ऊपर docstring में देख सकते हैं, आप भी स्पष्ट रूप से iterator-seq उपयोग करने की आवश्यकता नहीं हो सकता है। क्या आपने आरईपीएल में अनुक्रम के रूप में अपने जावा इटरेटर का इलाज करने का प्रयास किया था?

+0

यह काम नहीं करता है क्योंकि iterator-seq स्पष्ट रूप से केवल java.util.Iterator के साथ काम करता है, जबकि यहां वर्णित वस्तु एक info.aduna.iteration.Iteration है। Iterator-seq का उपयोग क्लासकास्ट अपवाद की ओर जाता है। – PaulaG