13

Sesameライブラリを使用して、メモリ内のトリプルストアでSPARQLクエリを実行しています。

私はこれを達成するためにClojureを使用しています。

クエリ結果はカスタムイテレータのような[1]オブジェクトであるため、clojureseqはそのままでは機能しません。

カスタムjavaIteratorのようなオブジェクトをclojureシーケンスに変換する最もエレガントな方法は何ですか?

私の頭に浮かんだ最も明白で愚かな考えは、それをループしてclojureベクトルを構築することですが、この問題にはもっとエレガントなアプローチがあると確信しています。

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

4

4 に答える 4

10

テストされたバージョン:

(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)))))))
于 2012-02-10T18:02:44.103 に答える
7

イテレータのようなオブジェクトを、実際にIteratorインターフェイスを実装するオブジェクトでラップするのはどうですか?次のようなもの(テストされていません):

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

私が知る限りIteration、標準Iteratorインターフェースに対するインターフェースの唯一の利点(それを呼び出したい場合)は、Clojureでは使用されないチェック済み例外を宣言できることです。

[更新:別の回答へのコメントで@amalloyによって提案されたように、iterator-seqの代わりに使用するようにコードを修正しました。]seq

于 2012-02-10T10:54:54.490 に答える
2

javaIterableおよびIterator用の純粋な関数型iterable-to-lazy-sequenceコード

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

カスタムイテレータの場合は、.iterator、.hasNext、および.nextの呼び出しを置き換えます。

利点は、引数として反復可能であるため、純粋関数型であるということです。他の投稿されたソリューションは、変更可能なイテレータ引数を取ります。そのため、関数は、参照透過性に違反する内部イテレータの状態に応じて、異なるシーケンスを返す可能性があります。機能もその怠惰さについて派手です。

于 2013-03-26T00:33:38.710 に答える
2

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明示的に使用する必要がない場合もあります。JavaイテレータをREPLのシーケンスとして扱ってみましたか?

于 2013-07-07T19:54:09.067 に答える