Ho un iteratore di righe da un file molto grande che deve essere inserito in gruppi mentre mi muovo. So dove finisce ogni gruppo perché c'è un valore sentinella sull'ultima riga di ogni gruppo. Quindi in pratica voglio scrivere una funzione che prende un iteratore e un valore sentinella, e restituisce un iteratore di gruppi ciascuno terminato dal valore sentinella. Qualcosa di simile:raggruppare gli elementi in un iterable cercando un valore sentinella (in scala)
scala> groups("abc.defg.hi.jklmn.".iterator, '.')
res1: Iterator[Seq[Char]] = non-empty iterator
scala> groups("abc.defg.hi.jklmn.".iterator, '.').toList
res19: List[Seq[Char]] = List(List(a, b, c, .), List(d, e, f, g, .), List(h, i, .), List(j, k, l, m, n, .))
Nota che desidero includere gli elementi sentinella alla fine di ogni gruppo. Ecco la mia soluzione attuale:
def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] {
def hasNext = iter.hasNext
def next = iter.takeWhile(_ != sentinel).toList ++ List(sentinel)
}
penso che questo funzionerà, e credo che sia bene, ma di dover aggiungere nuovamente la sentinella ogni volta che mi dà un odore di codice. C'è un modo migliore per farlo?
volevi una sentinella aggiunto all'ultimo gruppo se non contenerlo? (ad esempio "abc.def" -> ["abc.", "def."]) –
Idealmente no, anche se praticamente penso che non importi. – Steve
Succede che io abbia voluto e chiesto un 'takeTo' (più' dropTo' e 'spanTo'), che si comporterebbero come' takeWhile', ma restituiscono un elemento in più - il primo per cui il il predicato è vero. Se ti senti come me, potresti lasciare una nota qui: https://lampsvn.epfl.ch/trac/scala/ticket/2963 –