En utilisant scala, comment imprimer une chaîne dans les indices pairs et impairs d'une chaîne donnée? Je suis conscient de l'approche impérative en utilisant var
. Je recherche une approche qui utilise l'immuabilité, évite les effets secondaires (bien sûr, jusqu'au besoin d'imprimer le résultat) et concise.
4 Réponses :
val s = "abcd" // ac (0 until s.length by 2).map(i => s(i)) // bd (1 until s.length by 2).map(i => s(i)) just pure functions with map operator
Merci. Pourriez-vous s'il vous plaît expliquer le `` s (_) ''? Pouvez-vous s'il vous plaît poster un code équivalent désugarré pour moi?
@ dexter2305 Ne l'utilisez pas s'il s'agit d'une affectation ou d'une performance sensible. Vous devriez vraiment éviter l'accès aléatoire s (i)
pour les chaînes car il s'agit de O (n)
@SarveshKumarSingh. Je pensais que s (i)
appelle String :: charAt
sous le capot qui est le temps constant. Pourriez-vous expliquer plus en détail pourquoi c'est O (n)?
@SarveshKumarSingh Les chaînes ne sont que des wrappers sophistiqués sur Array [Char] , elles sont constantes de leur apply
.
@ LuisMiguelMejíaSuárez Oui, j'avais vraiment tort à ce sujet (je ne comprends pas pourquoi j'ai eu cette mauvaise impression) ... bon à savoir à partir de maintenant. docs.scala-lang.org/overviews/collections/…
Merci pour tous les commentaires
Une autre façon d'explorer est d'utiliser zipWithIndex
scala> val str = "1234" str: String = 1234 str.zipWithIndex res: scala.collection.immutable.IndexedSeq[(Char, Int)] = Vector((1,0), (2,1), (3,2), (4,3))
Dans ce cas, vous pouvez vérifier les résultats en utilisant la fonction imprimante
scala> printer(1) 24 scala> printer(0) 13
Je suggérerais de passer un Boolean au lieu d'un Int .
Voici une solution récursive de queue renvoyant des caractères pairs et impairs (List [Char], List [Char])
en une seule fois
val (even, odd) = f("abcdefg") println(even.mkString)
qui pourrait être imprimé comme tel
def f(in: String): (List[Char], List[Char]) = { @tailrec def run(s: String, idx: Int, accEven: List[Char], accOdd: List[Char]): (List[Char], List[Char]) = { if (idx < 0) (accEven, accOdd) else if (idx % 2 == 0) run(s, idx - 1, s.charAt(idx) :: accEven, accOdd) else run(s, idx - 1, accEven, s.charAt(idx) :: accOdd) } run(in, in.length - 1, Nil, Nil) }
Surtout du style, mais je préfère utiliser ::
pour préparer des éléments dans une Liste , cela rend évident à première vue que l'opération est un préfixe et que la collection préfixée est un list et rien d'autre pour lequel les préfixes peuvent être linéaires. (btw, bonne idée de commencer par la fin pour que la liste construite soit déjà dans l'ordre)
Vous pouvez utiliser la fonction glissant
, qui est assez simple:
scala> "abcdefgh".sliding(1,2).mkString("") res16: String = aceg scala> "abcdefgh".tail.sliding(1,2).mkString("") res17: String = bdfh