Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将类似java迭代器的对象转换为clojure序列_Java_Clojure_Seq_Sesame - Fatal编程技术网

如何将类似java迭代器的对象转换为clojure序列

如何将类似java迭代器的对象转换为clojure序列,java,clojure,seq,sesame,Java,Clojure,Seq,Sesame,我正在使用Sesame库在内存中的三重存储上运行SPARQL查询 我正在使用Clojure来实现这一点 查询结果是一个类似于[1]对象的自定义迭代器,因此clojure-seq不能直接处理它 将自定义java迭代器类对象转换为clojure序列最优雅的方法是什么 我脑海中出现的最明显和最愚蠢的想法是循环它并建立clojure向量,但我相信有更优雅的方法来解决这个问题 [1] 将类似迭代器的对象包装到实际实现迭代器接口的对象中如何?类似以下内容(未测试): 据我所知,Iteration接口相对于标

我正在使用Sesame库在内存中的三重存储上运行SPARQL查询

我正在使用Clojure来实现这一点

查询结果是一个类似于[1]对象的自定义迭代器,因此clojure-seq不能直接处理它

将自定义java迭代器类对象转换为clojure序列最优雅的方法是什么

我脑海中出现的最明显和最愚蠢的想法是循环它并建立clojure向量,但我相信有更优雅的方法来解决这个问题


[1]

将类似迭代器的对象包装到实际实现
迭代器接口的对象中如何?类似以下内容(未测试):

据我所知,
Iteration
接口相对于标准的
Iterator
接口的唯一优势(如果您想这样称呼它的话)是它允许声明已检查的异常,而Clojure中无论如何都不使用这些异常

[更新:按照@amalloy在对另一个答案的评论中的建议,更正代码以使用
迭代器seq
而不是
seq
。]

测试版本:

(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)))))))

java 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))))))
对于自定义迭代器,替换.iterator、.hasNext和.next调用

优点是它是纯函数式的,因为它将iterable作为参数。其他发布的解决方案采用迭代器参数,该参数是可变的,因此函数可能会根据内部迭代器状态返回不同的序列。 这个函数也炫耀它的懒惰。

为什么不试试呢


正如您在上面的docstring中所看到的,您甚至可能不需要显式地使用
迭代器seq
。您是否尝试将Java迭代器作为REPL中的序列处理?

谢谢。不完全正确,但它为我指明了正确的方向,并帮助我了解了具体化的实际使用。我已经得到了一个经过测试的正确版本,只是由于一些声誉限制,我还不能自我回答。:)这(具体化Iterable而不是迭代器)是一种方法;另一种方法是具体化迭代器,然后将其包装为。这不起作用,因为迭代器seq仅显式地与java.util.Iterator一起工作,而这里描述的对象是info.aduna.iteration.iteration。使用迭代器seq会导致ClassCastException。
(defn iter-seq
  ([iterable] 
    (iter-seq iterable (.iterator iterable)))
  ([iterable i] 
    (lazy-seq 
      (when (.hasNext i)
        (cons (.next i) (iter-seq iterable i))))))
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.