J'ai deux chaînes
val c = listOf(a, b) val d = c.flatMap { it.toList() }
Je veux le fusionner et j'ai besoin d'une sortie comme ci-dessous
J'ai ajouté les deux chaînes à arraylist, puis je l'ai flatmap
val a = "abc" val b = "xyz"
mais je n'obtiens pas le résultat souhaité
3 Réponses :
Utilisez la fonction zip
. Il crée une liste de paires avec des lettres «adjacentes». Vous pouvez ensuite utiliser joinToString
avec un transformateur pour créer votre résultat final.
a.zip(b) // Returns the list [(a, x), (b, y), (c, z)] .joinToString("") { (a, b) -> "$a$b" } // Joins the list back to a string with no separator
Joli. Je ne savais pas que zip
agit directement sur la chaîne comme un Iterable
, comme dans de nombreux langages FP. J'avais une solution similaire mais je faisais a.toList ()
et b.toList ()
.
@ m0skit0 exactement ma pensée, vraiment sympa :)
@ m0skit0 Kotlin fournit des surcharges pour CharSequence
s .
Vous pouvez toujours utiliser une boucle simple, en supposant que les deux chaînes ont la même taille. De cette façon, vous n'allouez qu'un StringBuilder
et une variable de compteur, sans listes
, tableaux
ou paires
:
val a = "abc" val b = "xyz" val sb = StringBuilder() for(i in 0 until a.length){ sb.append(a[i]).append(b[i]) } val d = sb.toString()
Fonctionne mais pas idiomatique. C'est Java écrit en Kotlin.
@ m0skit0 c'est plus efficace, mais pour un petit ensemble de données, ce n'est probablement pas pertinent. J'ai couru ceci et j'ai accepté la réponse dans JVM 10 millions de fois - boucle en moyenne 340 ms, zip 840 ms. Avec 184 caractères, la boucle de chaîne d'entrée était de 9,5 s, zip de 31 s.
@Pawel J'avais aussi la performance en tête. Jetez un œil à ma réponse
La lisibilité est généralement plus importante que les optimisations prématurées. Je peux immédiatement comprendre la réponse de Marstran. Pour le vôtre, je dois 1) lire plus de lignes de code et 2) comprendre ce que vous faites sur votre boucle for.
@WilliMentzel J'ai aussi bouclé cela, mais il semble avoir la même surcharge que zip, avec une moyenne de 850 ms sur 10 millions de boucles également.
@Pawel je ne l'ai pas vérifié, mais ce serait triste :(
@Pawel pourriez-vous publier un terrain de jeu avec votre benchmark? play.kotlinlang.org
@WilliMentzel J'avais l'habitude de le faire localement mais si vous voulez voir par vous-même: terrain de jeu .
@Pawel j'ai appris deux choses: la mienne est la plus lente (j'ai supprimé ma réponse xD) et la vôtre est la plus rapide, certainement tellement plus rapide que je sacrifierais la lisibilité pour cela (même si je pense que la lisibilité est bonne) :) merci pour le repère +1
La réponse de Marstran est vraiment concise et la réponse de Pawels est très rapide. Utilisation de Essayez-le ici: Kotlin Playground a >. Merci à Pawel d'avoir créé le benchmark original. buildString
a > vous pouvez avoir le meilleur des deux mondes: buildString {
a.zip(b).forEach { (a, b) ->
append(a).append(b)
}
}
buildString
crée un StringBuilder
et le propose comme récepteur dans le lambda. Il renvoie la chaîne construite.