En scala j'ai une liste de fonctions qui renvoient une valeur. L'ordre dans lequel les fonctions sont exécutées est important puisque l'argument de la fonction n
est la sortie de la fonction n-1
.Scala carte avec variables dépendantes
Ceci laisse présager d'utiliser foldLeft
, quelque chose comme:
val base: A
val funcs: Seq[Function[A, A]]
funcs.foldLeft(base)(x, f) => f(x)
(détail: le type A
est en fait un dataframe Spark).
Cependant, les résultats de chaque fonction s'excluent mutuellement et à la fin je veux l'union de tous les résultats pour chaque fonction. Ceci laisse présager d'utiliser un map
, quelque chose comme:
funcs.map(f => f(base)).reduce(_.union(_)
Mais ici chaque fonction est appliquée à base
qui est pas ce que je veux.
courte: Une liste de longueur variable des fonctions commandées doit renvoyer une liste de longueur égale des valeurs de retour, où chaque valeur est la n-1
entrée pour fonction n
(à partir de base
où n=0
). De telle sorte que les valeurs de résultat peuvent être concaténées.
Comment puis-je y parvenir?
EDIT exemple:
case class X(id:Int, value:Int)
val base = spark.createDataset(Seq(X(1, 1), X(2, 2), X(3, 3), X(4, 4), X(5, 5))).toDF
def toA = (x: DataFrame) => x.filter('value.mod(2) === 1).withColumn("value", lit("a"))
def toB = (x: DataFrame) => x.withColumn("value", lit("b"))
val a = toA(base)
val remainder = base.join(a, Seq("id"), "leftanti")
val b = toB(remainder)
a.union(b)
+---+-----+
| id|value|
+---+-----+
| 1| a|
| 3| a|
| 5| a|
| 2| b|
| 4| b|
+---+-----+
Cela devrait fonctionner pour un nombre arbitraire de fonctions (par exemple toA
, toB
... toN
où chaque calcul le reste du résultat précédent et est passé dans. la fonction suivante.A la fin une union est appliquée à tous les résultats
J'ai ajouté un exemple pour clarifier ma question. – Tim
Votre premier exemple était exactement ce dont j'avais besoin. Bonne idée pour accumuler dans une liste, jamais pensé que vous pourriez utiliser foldLeft comme ça. Impressionnant :). – Tim