seqsとiterator-seqの関係は次のとおりです。iterator-seqはイテレータからseqを作成します。
ここで冗長性を許しますが、「iterator-seqの出力を反復処理する方法」の質問に答えるには、最初にiterator-seqを呼び出す必要がある理由を最初に明確に定義する必要があります。
Clojureでは、iterator-seqオブジェクトを頻繁に作成する必要はありません。clojureは「Iterable」Javaオブジェクトの反復を非常に手軽に処理できるため(http://clojuredocs.org/clojure_core/clojure.core/iterator-seqを参照)。ただし、イテレータ自体は反復可能ではありません。
これを完全に理解するには、IterablesとIteratorsの違いを理解する必要があります。これは主に、Javaの世界でセマンティクスの一貫性と単純さを維持するためです。JavaのIteratorがIterableではないのはなぜですか。。
では、「seq」とは何ですか?
clojureには、ISeqのIteratorインターフェースであるjavaのIteratorインターフェースよりも高度な抽象化があります。iterator-seqは、内部でISeqを作成します。このISeqオブジェクトは、アイテムのシーケンシャルリストに対して動作する多くのClojure関数で使用できるようになりました。
user=> (iterator-seq (.iterator (new java.util.ArrayList ["A" "B"])))
("A" "B")
;Thus, we now have an ISeq implementation derived from an iterator.
したがって、「iterator-seq」関数は、JavaイテレータからのClojure「シーケンス」を作成しています。明確にするために-反復不可能なオブジェクトで「iterator-seq」を呼び出すときのエラーメッセージは有益です:
user=> (iterator-seq "ASDF")
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Iterator (NO_SOURCE_FILE:0)
これは、「iterator-seq」関数が入力としてjava.util.Iteratorを必要とすることを示しています。
あなたが持っているかもしれない次の論理的な質問は:
イテレータからシーケンスを作成する必要があるのはなぜですか?seq抽象化は、javaのイテレータ抽象化とどのように異なりますか?
Iterableインターフェースは、ClojureのISeqほど抽象的ではありません。たとえば、文字列について考えてみます。明らかに、文字列はシーケンシャルです。ただし、Javaでは反復できません。同じことがアレイにも当てはまります。
clojureのWebサイトから:
「seqはJava参照配列、Iterables、およびStringsで機能します。ライブラリの残りの多くはこれらの関数に基づいて構築されているため、ClojureアルゴリズムでJavaオブジェクトを使用するための優れたサポートがあります。」
したがって、iterator-seqの目的は、イテレータオブジェクトをシーケンス抽象化に「ラップ」することです。これにより、すべてのclojures機能機能を活用できるようになります。
iterator-seqの役割の定義
http://clojure.org/sequencesから:
「seq関数は、コレクションに適したISeqの実装を生成します。」
あなたの場合、私たちはそれを言うことができます:
「iterator-seq関数は、getIndexWordsIteratorのISeqの実装を生成します」。
最後に:どうすればseqを繰り返すことができますか?
文脈を考えると、この質問には注意深く答える必要があります。
反復は確かに可能ですが、clojureの主な関心事ではなく、実際にはあなたが求めているものではないかもしれません。iterator-seqはすでにSEQを作成しているので、Clojureの関数演算子(リスト内包表記、マップ関数など)の1つを使用してそのseqを使用できるようになりました。これにより、手動で繰り返す必要がなくなります。
たとえば、多くの場合、リストを反復処理して値を見つけます。clojureでは、フィルター関数を使用して値を見つけることができます。
user=> (filter #(= \A %) (seq "ABCD"))
(\A)
フィルタリングするのではなく、各オブジェクトを反復処理して関数を複数のオブジェクトに適用し、結果を新しいコレクションに保存したい場合があります。繰り返しますが、これは必要です-Clojureでの明示的な反復を介して行う必要はありません:
user=> (map #(.hashCode %) (seq "ABCZ"))
(65 66 67 90)
最後に、コレクションを手動で繰り返す必要がある場合は、Loop-recur構文を使用して、シーケンスを手動で末尾再帰的にトラバースできます。一度に1つの要素:http://clojure.org/functional_programming#Functional%20Programming --Recursive%20Looping。または、標準の再帰呼び出しを使用できます。