Dans scala, comment générer une liste de chaînes de hiérarchie - par exemple pour une société fournisseur qui fournit des services comme ci-dessous
scala> def hier_str(a:String,b:Int):String =
| {
|
| for(i<- a.zipWithIndex.filter(_._1=='/').map(x => x._2 ).zipWithIndex )
| if( i._2 == b )
| return a.substring(0,i._1)
|
| return a
|
| }
hier_str: (a: String, b: Int)String
scala> for(i<- 1 to 3) yield hier_str("/Vendor/Platform/DataServices",i)
res40: scala.collection.immutable.IndexedSeq[String] = Vector(/Vendor, /Vendor/Platform, /Vendor/Platform/DataServices)
scala>
à
/Vendor/ /Vendor/Platform/ /Vendor/Platform/DataServices
Pour le moment, j'utilise une fonction comme ci-dessous,
/Vendor/Platform/DataServices
Y a-t-il un meilleur moyen de le générer facilement en utilisant uniquement les fonctions intégrées?
p >
4 Réponses :
Essayez ceci:
a
.split("/")
.filter(_.nonEmpty)
.inits
.map(_.mkString("/","/",""))
.toList
.reverse
Cela inclut l'élément racine / donc ajoutez .drop (1) si vous ne le souhaitez pas ceci.
Cela peut être mieux ou non que du code utilisant des fonctions personnalisées ...
veuillez réviser value reverse n'est pas membre de Iterator [String]
il n'imprime pas à partir de la racine
@ stack0114106 Toutes mes excuses, cela a été cassé de tant de manières. Je l'ai réparé maintenant.
Ce que vous recherchez, c'est la méthode scanLeft , qui apparaît dans scala 2.8
Le scan fait simplement un pli et stocke le résultat intermédiaire:
/Vendor /Vendor/Platform /Vendor/Platform/DataServices
sortie lors de l'impression de chaque élément:
string.split('/').drop(1).scanLeft(""){(acc, next) => acc + "/" + next}.drop(1)
Consultez la documentation officielle https://www.scala-lang.org/ api / 2.12.3 / scala / collection / TraversableLike.html
Voici un scalafiddle pour le démontrer
il y a un élément vide à la fin. Vous devez le supprimer en utilisant drop (1)
@ stack0114106 Vous avez raison, j'ai édité ma réponse pour vous, répond-elle à vos besoins ou avez-vous besoin d'autre chose?
Cette petite fonction le ferait:
def split(path: String): String = {
val filteredList = path.split("/").zipWithIndex.filter(_._1.nonEmpty)
filteredList.map {
case (text, index) =>
(0 until index).map(i => filteredList(i)._1).mkString("/")
}.mkString("\n")
}
split("/Vendor/Platform/DataServices")
/* should output
Vendor/
Vendor/Platform/
Vendor/Platform/DataServices
*/
oui .. cela fonctionne aussi .. il suffit d'ajouter un autre / au premier mkString
Je pense que cela résoudra votre problème:
val str1="/Vendor/Platform/DataServices"
val p=str1.split('/').drop(1).scanLeft(""){case (x, y) => x + "/" + y}.drop(1).mkString("/"+"\n")
println(p)
c'est la même chose que la réponse acceptée .. veuillez vérifier avant de publier la réponse
Pourquoi pouvez-vous simplement diviser puis plier?
@RamanMishra .. pourriez-vous s'il vous plaît montrer que si cela aide à éviter la fonction, je vais bien