J'essaie de générer des numéros de séquence sur des éléments dupliqués. Il devrait se réinitialiser à 1 lorsque la valeur change, ceci donne résultat comme p> mais ce que j'attends est de l'obtenir comme < / p> Comment puis-je modifier la valeur de t à 0 lorsque la valeur change dans ma liste? p> Y a-t-il de meilleures méthodes pour obtenir la sortie ci-dessus? . p> p>
4 Réponses :
J'espère que cela aide.
scala> val dt = List("date", "date", "decimal", "decimal", "decimal", "string", "string")
dt: List[String] = List(date, date, decimal, decimal, decimal, string, string)
scala> val dtset = dt.toSet
dtset: scala.collection.immutable.Set[String] = Set(date, decimal, string)
scala> dtset.map( x => dt.filter( y => y == x))
res41: scala.collection.immutable.Set[List[String]] = Set(List(date, date), List(decimal, decimal, decimal), List(string, string))
scala> dtset.map( x => dt.filter( y => y == x)).flatMap(a => a.zipWithIndex)
res42: scala.collection.immutable.Set[(String, Int)] = Set((string,0), (decimal,1), (decimal,0), (string,1), (date,0), (date,1), (decimal,2))
scala> dtset.map( x => dt.filter( y => y == x)).flatMap(a => a.zipWithIndex).toList
res43: List[(String, Int)] = List((string,0), (decimal,1), (decimal,0), (string,1), (date,0), (date,1), (decimal,2)) // sort this list to your needs
Pour réinitialiser le compteur, vous devez regarder en arrière à l'élément précédent, lequel .map () code> ne peut pas faire. dt.foldLeft(List.empty[(String,Int)]){ case (lst,str) =>
lst.headOption.fold((str,1)::Nil){
case (`str`,cnt) => (str,cnt+1) :: lst
case _ => (str,1) :: lst
}
}.reverse
//res0: List[(String, Int)] = List((date,1), (date,2), (decimal,1), (decimal,2), (decimal,3), (string,1), (string,2))
Pourriez-vous s'il vous plaît ajouter quelques explications .. Il y a un pli imbé de la façon dont cela fonctionne?
@ stack0114106; Explication ajoutée
En ajoutant une autre variable de chaîne mutable, la ci-dessous fonctionne. Résultats: P> val dtg = dt.groupBy(identity).map( x => (x._2 zip (Stream from 1)) ).flatten.toList
Vous pouvez remplacer x._2 zip x._2.indices.map (_ + 1) code> avec x._2 zip (flux de 1) code>.
La meilleure méthode à utiliser pour cela est à chaque étape, il incrémente le nombre si la valeur est identique à celle précédente, sinon elle le réinitialise à 1. P> Cela fonctionnera si la liste a un seul élément. Bien que Ce sera ne fonctionnera pas fort> si la liste est vide, comme scanleft code> qui est comme repliolft code> mais émet une valeur à chaque étape. Le code ressemble à ceci:
queue code> sera nil code>, le premier élément du résultat de scanleft code> est toujours le premier paramètre à la méthode. Dans ce cas, il est (ds.head, 1) code>. P> DS. tête code> lancera une exception. Cela peut être corrigé à l'aide d'un p> p>
Avec un seul élément aussi, cela fonctionne .. Comment ça va ?. Le DS.TAIL renvoie la liste vide .. Pourriez-vous faire une certaine lumière
Pourriez-vous jeter un coup d'œil sur
Et si vous aviez une liste
("date", "chaîne", "date") code>?Liste (((date ", 1), (" chaîne ", 1), (" date ", 1)) code>? L'ordre de résultat est-il significatif?@jwvh .. non .. c'est la raison pour laquelle j'ai utilisé
trié code> dans ma question