2015-05-15 17 views
5

In Haskell, c'è una funzione chiamata fromListWith che può generare una mappa da una funzione (utilizzato per unire valori con la stessa chiave) e un elenco:In Scala, c'è un equivalente di Haskell "fromListWith" per Map?

fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a 

La seguente espressione verrà valutato per true:

fromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")] 

In Scala, v'è una funzione simile denominata toMap su List oggetti, che può anche convertire un elenco ad una mappa, ma non può avere un parametro della funzione a che fare con le chiavi duplicate.

Qualcuno ha idee a riguardo?

risposta

8

Oltre ad utilizzare scalaz si potrebbe anche definire uno voi stessi:

implicit class ListToMapWith[K, V](list: List[(K, V)]) { 
    def toMapWith(op: (V, V) => V) = 
    list groupBy (_._1) mapValues (_ map (_._2) reduce op) 
} 

Ecco un esempio di utilizzo:

scala> val testList = List((5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")) 
scala> testList toMapWith (_ + _) 
res1: scala.collection.immutable.Map[Int,String] = Map(5 -> aba, 3 -> ba) 
+0

stavo per scrivere qualcosa di simile. +1 per avermi insegnato che 'mapValues' esiste. –

+2

Si noti che 'mapValues' restituisce una vista che ricalcolerà il valore su ogni accesso, che potrebbe non essere desiderabile in questo caso. –

3

Lo stdlib non dispone di tale funzionalità, tuttavia, è disponibile una porta di Data.Map disponibile in scalaz per cui questa funzione è disponibile per does have.