En Scala, comment puis-je faire l'équivalent d'un SQL SOMME et de GROUPE?
Par exemple, supposons que j'ai
val list: List[(String, Double)]
avec des valeurs
"04-03-1985", 1.5
"05-03-1985", 2.4
"05-03-1985", 1.3
Comment ai-je pu produire une nouvelle Liste
"04-03-1985", 1.5
"05-03-1985", 3.7
OriginalL'auteur deltanovember | 2011-08-22
Vous devez vous connecter pour publier un commentaire.
Voici un one-liner. Ce n'est pas très lisible, à moins de vraiment intériorise les types de ces des fonctions d'ordre supérieur.
Une autre approche consiste à ajouter les paires clé-valeur d'un-à-un à l'aide de pli,
L'équivalent pour la compréhension est le plus accessible, à mon avis,
Peut-être quelque chose de plus sympa peut être fait avec Scalaz du monoïde typeclass pour la Carte.
Notez que vous pouvez convertir entre
Map[K, V]
etSeq[(K, V)]
à l'aide de latoSeq
ettoMap
méthodes.Mise à jour. Après y réfléchissant un peu plus, je pense que le naturel de l'abstraction serait un "multimap" conversion de type,
Avec les implicites de l'extension dans une bibliothèque personnelle, on peut alors écrire:
C'est le meilleur de tous, à mon avis!
Ouais, j'ai édité mon post pour se qualifier "lisibilité" -- pour quelqu'un qui est profondément familier avec le sens de l'
groupBy
etmapValues
, OK, la version concise est la meilleure. Mais il est difficile de en déduire le sens de ces fonctions à partir de l'expression concise, et pour rusty Scala programmeurs (comme moi) je pense que la compréhension serait la plus facile à comprendre.Je l'ai lu de post-édition. Je n'avais jamais entendu parler de soit groupBy et mapValues (je suis nouveau à la Scala), mais ils étaient exactement ce que j'ai espérait Scala aurait. De gustibus non disputandum comme ma mère a toujours dit, mais votre première solution a le minimum de trucs et j'ai donc trouver le plus accessible.
J'apprécie votre point de vue. Quand je rencontre des modèles de programmation, qui repoussent les limites de mon mémoire de travail, je trouve souvent il est utile d'abstraction qui simplifie grandement les choses. Dans ce cas, je pense que le droit d'abstraction est
toMultimap
. Un autre exemple: le typeclasses en Haskell/Scalaz comme Foncteur, Applicative, Monade..., ont un coût à apprendre, mais une fois compris, leur application simplifie ultérieure de haut niveau de modèles.Le plus clair serait quelque chose comme
s.groupBy(_._1).mapValues(_.sumBy(_._2))
. Ayant conversions implicites qui ne sumBy, avgBy pourrait être assez cool.OriginalL'auteur Kipton Barros
Il y a une autre possibilité, à l'aide de Scalaz.
Le point clé est d'avis que, si
M
est unMonoid
, puisMap[T, M]
est aussi unMonoid
. Cela signifie que si j'ai 2 cartes,m1
etm2
que je peux ajouter, de sorte que, pour chaque clé similaires, les éléments seront ajoutés ensemble.Par exemple,
Map[String, List[String]]
est un Monoïde parce queList[String]
est unMonoid
. Le cas échéantMonoid
exemple dans le champ d'application, je devrais être capable de faire:Pour votre question, nous pouvons voir que
Map[String, Int]
est unMonoid
car il y a unMonoid
exemple pour laInt
type. Nous allons importer:Puis j'ai besoin d'une fonction
reduceMonoid
, qui prend tout ce qui estTraversable
et ajoute" ses éléments avec unMonoid
. Je viens d'écrire lereduceMonoid
de définition, de mise en œuvre complète, veuillez vous référer à mon post sur le L'Essence de l'Itérateur Modèle:Ces 2 définitions n'existent pas dans le courant de Scalaz de la bibliothèque, mais ils ne sont pas difficiles à ajouter (sur la base de
Monoid
etTraverse
typeclasses). Et une fois que nous les avons, la solution à votre question est très simple:Si vous estimez que le code ci-dessus est un peu obscure (mais vraiment concis, non?), Je vous invite à consulter le projet github pour les EIP post et de jouer avec elle. Un exemple montre la solution à votre question:
+1. Vous devriez probablement commencer à bloguer à propos de ces simples cas d'utilisation où l'on peut commencer à intégrer Scalaz dans leur projet. 🙂 Va encourager plus de gens à regarder dans Scalaz et algébrique de la programmation fonctionnelle.
OriginalL'auteur Eric
J'ai utilisé ce modèle
s.groupBy(_._1).mapValues(_.map(_._2).sum)
de Kipton la réponse de tous les temps. Il traduit assez directement mon processus de pensée, mais malheureusement n'est pas toujours facile à lire. J'ai trouvé que l'utilisation de la classe de cas chaque fois que possible, rend les choses un peu mieux:Il devient alors:
Je pense que c'est plus lisible que le fois ou pour version.
OriginalL'auteur huynhjl
OriginalL'auteur anrizal - Anwar Rizal