2010-07-12 2 views
5

이동하는 동안 그룹으로 묶어야하는 매우 큰 파일의 회선 반복자가 있습니다. 각 그룹의 마지막 줄에 센티넬 값이 있기 때문에 각 그룹이 어디에서 끝나는 지 알고 있습니다. 그래서 기본적으로 반복자와 센티널 값을 취하고 각 센티넬 값에 의해 종료 된 그룹의 반복자를 반환하는 함수를 작성하려고합니다. 다음과 같음 :센티넬 값 (스칼라로)을 검색하여 반복 가능 항목을 그룹화합니다.

각 그룹의 끝에 포함 된 감시 항목이 필요합니다. 여기 내 현재 솔루션이다 :

def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] {     
    def hasNext = iter.hasNext 
    def next = iter.takeWhile(_ != sentinel).toList ++ List(sentinel) 
} 

나는이 일을 생각하고, 나는 그것이 좋은 것 같아요,하지만 다시 추가 센티넬에있는 것은 때마다 나에게 코드 냄새를 제공합니다. 이 작업을 수행하는 더 좋은 방법이 있습니까? 재귀

def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] { 
def hasNext = iter.hasNext 
def next: Seq[T] = { 
    val builder = scala.collection.mutable.ListBuffer[T]() 
    while (iter.hasNext) { 
     val x = iter.next 
     builder.append(x) 
     if (x == sentinel) return builder 
    } 
    builder 
} 
} 

또는 :

def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] { 
    def hasNext = iter.hasNext 
    def next: Seq[T] = { 
     @scala.annotation.tailrec 
     def build(accumulator: ListBuffer[T]): Seq[T] = { 
     val v = iter.next 
     accumulator.append(v) 
     if (v == sentinel || !iter.hasNext) => accumulator 
     else build(accumulator) 
     } 
     build(new ListBuffer[T]()) 
    } 
    } 
+0

만약 그것이 포함되어 있지 않으면 마지막 그룹에 감시 원을 추가하길 원했습니까? (예 : "abc.def"-> [ "abc.", "def."]) –

+0

이상적으로는 아니지만 실제적으로는 중요하지 않다고 생각합니다. – Steve

+0

'takeTo' (더하기'dropTo'와'spanTo')는'takeWhile'와 똑같이 작동하지만 하나 더 많은 요소를 반환하기를 원했고 요청했습니다. 술어는 사실입니다. 당신이 나를 좋아한다면, 여기에 메모를 남길 수 있습니다 : https://lampsvn.epfl.ch/trac/scala/ticket/2963 –

답변

2

미운하지만, 더해야 당신보다 덜 읽을 수 있지만, 최종 그룹이 종료 센티넬 값이없는 경우보다 "올바른"

+0

와우, 추악하지만 시원합니다. =) "var last"를 private 변수로 옮길 수 있습니다. 그러면 좀 덜보기 흉하게 보입니다. – Steve

5

당신의 솔루션보다 성능이 좋습니다 :

def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] {     
    def hasNext = iter.hasNext 
    def next = iter.takeWhile{ 
     var last = null.asInstanceOf[T] 
     c => { val temp = last; last = c; temp != sentinel} 
    }.toList 
    } 
관련 문제