10
votes

Comment utiliser à cause d'un itérateur à Scala

J'ai un itérateur d'éléments et je veux les consommer jusqu'à ce qu'une condition soit remplie dans l'élément suivant, comme: xxx

res1 donne un < Code> Liste (1,1,1,1) Mais res2 renvoie la liste (2,2) car itérateur a dû vérifier l'élément en position 4.

Je sais que la liste sera commandée, il est donc notamment de traverser toute la liste comme partition . J'aime finir dès que la condition n'est pas remplie. Y a-t-il un moyen intelligent de le faire avec des itérateurs? Je ne peux pas faire un tolist à l'itérateur car il provient d'un très gros fichier.


0 commentaires

5 Réponses :


0
votes

Vous pouvez utiliser la méthode tostream sur itérateur .

flux est un équivalent paresseux de la liste .

Comme vous pouvez le voir sur implémentation de tostream Il crée un flux sans traverser l'intégruteur itérateur . < p> flux garde tout élément en mémoire. Vous devez localiser l'utilisation du lien vers flux dans une portée locale pour éviter les fuites de mémoire.

avec Vous devez utiliser span Comme ceci: xxx


4 commentaires

Mais le flux a un énorme inconvénient, il faut savoir: Contrairement à Itérateur IT Garde tous les articles Il a lu la mémoire.


@ OM-NOM-NOM: OP a besoin de tous les articles s'il veut réitérer la collecte. Et flux garde des éléments uniquement pendant qu'il existe un lien vers le premier élément.


Mais alors, la première fois que j'exécute la première fois que je reçois un ruisseau (1, 1, 1, 1, 2,?) Et la deuxième victime commence à partir du début du flux (1, 1, 1, 1, 2, 2 ,? ) donner un flux vide


@cechu: Désolé, j'ai mal compris la question. Si vous voulez le même comportement que avec itérateur , vous pouvez utiliser span méthode du flux , mais il est préférable d'utiliser itérateur , comme @ @ OM-NOM-NOM mentionné.



0
votes

Je suppose un peu ici, mais par la déclaration "jusqu'à ce qu'une condition soit remplie dans l'élément suivant" , on sonne comme si vous souhaitez que vous souhaitiez regarder le Group Quand Méthode sur lutch lutopes dans scalaz xxx

essentiellement cette séquence d'entrée sur une condition (un (A , A) => booléen ) se réunit entre un élément et son successeur. Dans l'exemple ci-dessus, l'égalité est égale à l'égalité, tant que l'élément est égal à son successeur, ils seront dans le même morceau.


3 commentaires

Oui, c'est la fonctionnalité que je recherchais, mais le problème est que je ne peux pas tenir en mémoire le résultat du groupe. Je reçois des valeurs via une itératrice de lecture d'un grand fichier. Un groupe quand des itérateurs existent-il à Scalaz?


Non - Scalaz n'a pas "comme" les itérateurs (ils ne sont pas pures). Ils ont une classe appelée éphéméralstream . Il ne vient pas avec un Group quand mais vous pouvez en écrire une seule fois, étant donné que c'est un monad . Je ne garantirais pas ça ne déborde pas de la pile!


J'ai ajouté une réponse différente ci-dessous, montrant comment vous pouvez ajouter Groupby à un itérateur en utilisant la fonctionnalité itérator.duplicate .



3
votes

Avec mon autre réponse (que je suis restée séparée comme ils sont en grande partie non liées), je pense que vous pouvez implémenter GroupQu. / code> sur itérateur code> comme suit:

println( groupWhen(List(1,1,1,1,3,4,3,2,2,2).iterator)(_ == _).toList )


1 commentaires

Attention à ce que cette mise en œuvre déposera les éléments où le prédicat renvoie faux. Mieux utiliser la mise en œuvre de Borice.



3
votes

J'avais un besoin similaire, mais le Solution de @oxbow_Lakes ne prend pas en compte la situation lorsque la liste a un seul élément, ou même si la liste contient des éléments qui ne sont pas répétés. En outre, cette solution ne se prête pas à un itérateur infini (il veut "voir" tous les éléments avant de vous donner un résultat).

Ce dont j'avais besoin était la possibilité de collecter des éléments séquentiels qui correspondent à un prédicat, Mais incluez également les éléments simples (je peux toujours les filtrer si je n'en ai pas besoin d'eux). J'avais besoin que ces groupes soient livrés en permanence, sans avoir à attendre que l'itérateur d'origine soit complètement consommé avant de produire. P>

J'ai proposé l'approche suivante qui fonctionne pour mes besoins et pensais que je devrais Partager: P>

Stream.continually(Random.nextInt(100)).iterator
      .groupWhen(_ + _ == 100).withFilter(_.length > 1).take(3).toList


0 commentaires

4
votes

La solution la plus simple que j'ai trouvée: xxx

sortie: xxx

très court mais vous devez utiliser nouvel itérateur.

avec une collection immuable, il serait similaire:

  • Utilisez-le à l'épreuve lorsque vous ne voulez que du préfixe de la collection,
  • Utilisez la portée lorsque vous avez besoin de repos aussi.

0 commentaires