【Scala】Iterator

Iteratorについてまとめ。
Scalaでリスト処理 と
["collections"] - イテレータ - Scala Documentation
を参考にしてます。

・Itreratorはコレクションではない

SeqやListなどのコレクションとよく似ているが、イテレータはコレクションから要素を1つづつアクセスするための方法だ。そのためイテレータ自体を出力することは出来ない。

//List
scala> var list = (1,2,3)
list: (Int, Int, Int) = (1,2,3)

scala> print(list)  //printでリストを出力
(1,2,3)

//Iterator
scala> var it = Iterator(1,2,3)
iterator: Iterator[Int] = non-empty iterator  

scala> print(it)  //「方法」を出力することは出来ない
non-empty iterator


・要素を一度しか参照できない

1度参照した要素は削除される。要素を残しておきたいなら別の変数に代入しておく必要がある

//List
scala> list.size
res: Int = 3

scala> list
res: List[Int] = List(1, 2, 3)

//Iterator
scala> it.size
res: Int = 3

scala> it
res: Iterator[Int] = empty iterator  //空になっている


・基本的な演算には next と hasNext を使う

Iterator(以降it).next で次の要素を返し、イテレータの内部状態を前進させる。よって同じイテレータにnextを呼び出すと前回返した次の要素が返ってくる。

scala> it = list.toIterator
res: Iterator[Int] = non-empty iterator  //リストをイテレータに変換

scala> it.next
res: Int = 1  //最初の要素が返ってくる

scala> it.next
res: Int = 2  //次の要素が返ってくる



返す要素が無くなると、next の呼び出しは例外(NoSuchElementException)を発生させる

scala> it.next
res: Int = 3

scala> it.next
java.util.NoSuchElementException: next on empty iterator  //例外発生



返す要素の有無はhasNextで判断できる

scala> it.hasNext
res: Boolean = false  

scala> it = list.toIterator
it: Iterator[Int] = non-empty iterator

scala> it.hasNext
res: Boolean = true



whileループに next と hasNextを使って全要素を参照できる

scala> while(it.hasNext)println(it.next)
1
2
3



forループを使って参照することも出来る

scala> for (i<-it)println(i)
1
2
3



foreachを使ってさらに短縮可能

scala> it foreach println
1
2
3


メソッドはリストなどのコレクションと同じように使える

上の foreach などもそうだが、scalaのイテレータはTraversable,Iterable及びSeqクラスのほとんどのメソッドに類似するものを使うことが出来る。map演算とかも可能

scala> it.map(_+1) foreach println
2
3
4



Itetatorに関してはこんな感じ。


最後に前回使った permutations 関連のメソッドを少しまとめ。
これらはイテレータを利用しているだけで、イテレータのメソッドではないので注意

  • permutations リストの全ての順列を返す
scala> list.permutations foreach println
List(1, 2, 3)
List(1, 3, 2)
List(2, 1, 3)
List(2, 3, 1)
List(3, 1, 2)
List(3, 2, 1)


  • combinations(n) リストの全ての組み合わせを返す
scala> list.combinations(2) foreach println
List(1, 2)
List(1, 3)
List(2, 3)


  • sliding(n) リストから連続する n 個の要素からなるリストを返す
scala> 1 to 10 sliding(4) foreach println
Vector(1, 2, 3, 4)
Vector(2, 3, 4, 5)
Vector(3, 4, 5, 6)
Vector(4, 5, 6, 7)
Vector(5, 6, 7, 8)
Vector(6, 7, 8, 9)
Vector(7, 8, 9, 10)