J'ai un itérateur de lignes à partir d'un très gros fichier qui doit être mis en groupes au fur et à mesure que je progresse. Je sais où chaque groupe se termine parce qu'il y a une valeur sentinelle sur la dernière ligne de chaque groupe. Donc, fondamentalement, je veux écrire une fonction qui prend un itérateur et une valeur sentinelle, et retourne un itérateur de groupes terminés par la valeur sentinelle. Quelque chose comme:regrouper des éléments dans un itérable en recherchant une valeur sentinelle (en 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, .))
Notez que je veux les éléments sentinelles inclus à la fin de chacun des groupes. Voici ma solution actuelle:
def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] {
def hasNext = iter.hasNext
def next = iter.takeWhile(_ != sentinel).toList ++ List(sentinel)
}
Je pense que cela va fonctionner, et je pense qu'il est très bien, mais avoir à ajouter de nouveau la sentinelle à chaque fois que me donne une odeur de code. Y a-t-il une meilleure manière de faire cela?
Souhaitez-vous ajouter une sentinelle au dernier groupe s'il ne l'a pas contenue? (par exemple "abc.def" -> ["abc.", "def."]) –
Idéalement non, même si pratiquement je pense que cela n'a pas d'importance. – Steve
Il se trouve que j'ai voulu, et demandé, un 'takeTo' (plus' dropTo' et 'spanTo'), qui agirait comme' takeWhile', mais retourner un élément de plus - le premier pour lequel le le prédicat est vrai. Si vous vous sentez comme moi, vous pouvez laisser tomber une note ici: https://lampsvn.epfl.ch/trac/scala/ticket/2963 –