2017-11-21 7 views
1

나는 String의 매우 많은 양을 반복 일부 반복자가변 변수없이 Iterator를 즉석에서 수정하는 방법은 무엇입니까?

val i: Iterator[String] = //.. 

있습니다. 따라서 메모리에있는 모든 내용을로드 할 수 없습니다. 소스 이터레이터의 각 요소 사이에 구분 기호 (예 : "separator")를 삽입하는 Iterator[String]을 생성해야합니다.

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을 사용하여 각 요소를 요소로 바꾼 다음 구분 기호로 바꿀 수 있습니다. 마지막에 최종 분리를 방지하기 위해, 당신은 여전히 ​​반복자의 요소가 있는지 여부를 확인하는 if 추가 할 수 있습니다 : 칼 Bielefeldt의 제안에 따라,

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

또는를 먼저 분리를 넣고 drop을 사용할 수 있습니다 대신 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'가 비어있는 경우 드롭이 작동하는 이유는 무엇입니까? –