10
votes

Scala, prolongeant l'itérateur

Je cherche à étendre l'itérateur pour créer une nouvelle méthode à prendre en main , qui fonctionnera comme à l'épreuve mais inclure le dernier élément.

Mon problème est ce qui est le meilleur Pratique pour étendre l'itérateur pour retourner un nouvel itérateur que j'aimerais être paresseux évalué. Venant d'un arrière-plan C # I Utilisation normale iEnumerable et utilisez le mot-clé de rendement , mais une telle option n'apparaît pas exister dans Scala.

pour Exemple que je pourrais avoir xxx

donc dans ce cas, le primé à prendre en charge n'aurait que résoudre le prédicat sur les valeurs jusqu'à ce que je reçois un résultat supérieur à 6 , et il inclura ce premier résultat

jusqu'à présent que j'ai: xxx


3 commentaires

Avez-vous eu un coup d'oeil au flux?


Un flux pourrait certainement être plus approprié ici dans l'exemple, mais j'ai toujours le même problème autour de la meilleure façon de construire la méthode de l'extension


Oh, Main-à-Maître . Mon ancien Taketo ....


5 Réponses :


0
votes
scala> def timeConsumeDummy (n: Int): Int = {
     | println ("Time flies like an arrow ...") 
     | n }
timeConsumeDummy: (n: Int)Int

scala> List(0,1,2,3,4,5,6,7).toStream.filter (x => timeConsumeDummy (x) < 6) 
Time flies like an arrow ...
res14: scala.collection.immutable.Stream[Int] = Stream(0, ?)

scala> res14.take (4).toList 
Time flies like an arrow ...
Time flies like an arrow ...
Time flies like an arrow ...
res15: List[Int] = List(0, 1, 2, 3)

4 commentaires

Désolé, l'exemple n'est pas le cas spécifique que je cherche à résoudre, je comprendrai un exemple plus approfondi pour illustrer ce que je suis après


@Jpullar: Votre prise (2) a disparu et a changé de place avec (_ <6), tandis que le TimeconsumingMethod est à gauche de (_ <6) maintenant. Ainsi, (TimeconsumingMethod) produit un INT en résultat, ce qui est comparé à (_ <6) maintenant, ou est-ce l'élément de liste initiale, qui doit être inférieur à 6?


Ce que votre projection est correcte et ce que je suis après dans l'évaluation paresseuse. Mon problème, cependant, consiste à imiter la manière dont la fonction de filtre est évaluée paresseusement dans une méthode d'extension personnalisée


Donc, si TIMECONSUMEDY retourne 2 * N - 1 , tous les calculs sont effectués, c'est vrai.



11
votes

Vous pouvez utiliser la méthode span de itérateur pour le faire assez proprement: xxx

maintenant (0 jusqu'à 10 ) .toalerator.Tolat-questionné (_ <4) .tolist donne Liste (0, 1, 2, 3, 4) , par exemple.


1 commentaires

La dernière ligne de votre méthode peut être écrite plus succinctement que a ++ (b prendre 1)



2
votes
object ImplicitIterator {
  implicit def extendIterator[T](i : Iterator[T]) = new IteratorExtension(i)
}

1 commentaires

C'était là que ma pensée se dirigeait, merci d'y arriver pour moi! Il offre une bonne approche généralisée. Je souhaite qu'il y ait une solution générale plus élégante puis de construire un nouvel itérateur.



7
votes

Ceci est un cas où je trouve la solution mutable supérieure: xxx


4 commentaires

Ceci est définitivement une solution élégante à mon problème, acclamations!


Je prendrai la version fonctionnelle avec ni var s ni val s, merci!


@OXBOW_LAKES - Si cela ne vous dérange pas des frais généraux supplémentaires, c'est une alternative fine. (Normalement, je n'utiliserais pas un Val pour la fonction; J'essayais simplement de séparer les choses pour plus de clarté.)


C'était plus le var je vous ai opposé! Et je n'étais pas particulièrement sérieux de toute façon



3
votes

Les éléments suivants nécessitent Scalaz pour obtenir plier sur un tuple (a, b) xxx

ici il est au travail: < / p> xxx

Vous pouvez rouler votre propre pli sur une paire comme ceci: xxx


0 commentaires