0
votes

SCALA - Réinitialiser à 1 lorsque la valeur dupliquée change dans une liste

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, xxx

ceci donne résultat comme xxx

mais ce que j'attends est de l'obtenir comme < / p> xxx

Comment puis-je modifier la valeur de t à 0 lorsque la valeur change dans ma liste?

Y a-t-il de meilleures méthodes pour obtenir la sortie ci-dessus? .


2 commentaires

Et si vous aviez une liste ("date", "chaîne", "date") ? Liste (((date ", 1), (" chaîne ", 1), (" date ", 1)) ? L'ordre de résultat est-il significatif?


@jwvh .. non .. c'est la raison pour laquelle j'ai utilisé trié dans ma question


4 Réponses :


2
votes

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


0 commentaires

3
votes

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))


2 commentaires

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



2
votes

En ajoutant une autre variable de chaîne mutable, la ci-dessous fonctionne. XXX PRE>

Résultats: P>

val dtg = dt.groupBy(identity).map( x => (x._2 zip (Stream from 1)) ).flatten.toList


1 commentaires

Vous pouvez remplacer x._2 zip x._2.indices.map (_ + 1) avec x._2 zip (flux de 1) .



3
votes

La meilleure méthode à utiliser pour cela est scanleft qui est comme repliolft mais émet une valeur à chaque étape. Le code ressemble à ceci: xxx

à chaque étape, il incrémente le nombre si la valeur est identique à celle précédente, sinon elle le réinitialise à 1.


Cela fonctionnera si la liste a un seul élément. Bien que queue sera nil , le premier élément du résultat de scanleft est toujours le premier paramètre à la méthode. Dans ce cas, il est (ds.head, 1) .

Ce sera ne fonctionnera pas si la liste est vide, comme DS. tête lancera une exception. Cela peut être corrigé à l'aide d'un xxx


2 commentaires

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 Stackoverflow.com/questions/55929119/...