2017-06-22 2 views
0

Supposons que je besoin d'une fonction pour filtrer les caractères de chars d'une chaîne str puis ne prendre que k premiers caractères du résultat:Comment traiter paresseusement deux chaînes à la fois?

def cleanTrim(str: String, chars: Set[Char], k: Int): String = 
    str.filterNot(chars).take(k) 

Cette mise en œuvre est sous-optimale car il scanne inutilement la chaîne entière. Afin d'optimiser l'on peut utiliser view ou d'un événement Stream pour scanner l'entrée paresseusement, par exemple:

def cleanTrim(str: String, chars: Set[Char], k: Int): String = 
    str.view.foldLeft("") { case (r, c) => if (chars.contains(c)) r + c else r }.take(k) 

Supposons maintenant que je dois nettoyer et dégraisser paresseusement deux cordes. Je voudrais les traiter paresseusement pour traiter un seul personnage à la fois et retourner les deux résultats.

def cleanTrim2(str1: String, 
       str2: String, 
       chars: Set[Char], 
       k: Int): (String, String) = ??? 

Comment pourriez-vous le mettre en œuvre?

+0

Vous prenez en deux chaînes, filtre eux et renvoyer une seule chaîne? Lequel retournez-vous? –

+0

Mon erreur. Je dois retourner les deux. Mise à jour de la question – Michael

+0

Pourquoi ne pas prendre une séquence, la replier et la renvoyer? –

Répondre

3

Je ne vois aucun avantage à utiliser la paresse. Dans votre deuxième mise en œuvre de cleanTrim vous continuez d'analyser toute la chaîne, en fait vous ne pouvez pas vérifier si la chaîne contains char sans balayer la chaîne entière (ou stream ou view). UPD: @thwiegan droite, je n'ai pas lu la question attentivement.

UPD2: Ok, mon deuxième essai, ne sais pas s'il est important pour vous d'utiliser fold, mais je vois la façon de le rendre plus clair:

def cleanTrim2(str1: String, str2: String, chars: Set[Char], k: Int): (String, String) = { 
     val result1 = str1.iterator.filterNot(chars).take(k).mkString 
     val result2 = str2.iterator.filterNot(chars).take(k).mkString 
     (result1, result2) 
    } 
+1

Il n'a besoin que d'un certain nombre de caractères de cette chaîne. Donc, s'il a une chaîne de longueur 20 et qu'il n'a besoin que de 10 (k), il doit seulement scanner jusqu'à ce qu'il ait ces 10 caractères, qui ne sont pas dans le jeu de caractères. Vous avez raison sur la deuxième implémentation, mais je pense qu'il a juste oublié de mettre le 'take (k)' à la fin (ce que j'ai souligné dans mon commentaire). – thwiegan