2017-11-21 9 views
1

私はいくつかのイテレータ可変変数なしでIteratorをオンザフライで修正するにはどうすればよいですか?

String秒の非常に大きな量を反復さ
val i: Iterator[String] = //.. 

を持っています。したがって、すべての内容をメモリにロードすることはできません。私はIterator[String]を生成して、ソースイテレータの各要素の間にセパレータ(たとえば"separator")を挿入する必要があります。

class SeparatedIterator(i: Iterator[String]) extends Iterator[String] { 
    private var pointToElement = false 

    override def hasNext: Boolean = 
     if (pointToElement && i.hasNext) true 
     else i.hasNext 

    override def next(): String = 
     if(pointToElement && i.hasNext) { 
     pointToElement = false 
     "separator" 
     } 
     else if (i.hasNext) { 
     pointToElement = true 
     i.next() 
     } else throw new NoSuchElementException 
    } 

これを行うための機能的な方法があります:例としては、

["1", "2", "3"] --> ["1", "separator", "2", "separator", "3"] 
["1", "2"] --> ["1", "separator", "2"] 
["1"] --> ["1"] 
[] --> ["1"] 

は私が変更可能な変数と解決策を見つけましたか?可変変数なし?

答えて

4

入力イテレータでflatMapを使用して、各要素を要素で置き換え、その後にセパレータを置き換えることができます。

def separatedIterator(iter: Iterator[String]): Iterator[String] = { 
    iter.flatMap { x => 
     if (iter.hasNext) Iterator(x, "separator") 
     else Iterator(x) 
    } 
} 

あるいは、カールBielefeldtの提案どおり、あなたが最初のセパレータを配置し、dropを使用することができます。最後に、最終的な区切りを回避するには、イテレータの要素がまだあるかどうかを確認ifを追加することができます代わりにifのそれを取り除くために:

def separatedIterator(iter: Iterator[String]): Iterator[String] = { 
    iter.flatMap { x => Iterator("separator", x) }.drop(1) 
} 
+4

をあなたが最初のセパレータを入れた場合は、 'ITER flatMap {「区切り」:: _ ::無記号}は '1'ドロップ第一セパレータを削除する操作を行うことができます。 –

+0

@KarlBielefeldtこれはいいアイデアです、ありがとう。 – sepp2k

+0

しかし、 'Iterator'が空のときにドロップがなぜ機能しますか? –

関連する問題