una tuplas tupla son qué que lista las eliminar elemento ejemplos convertir como cadenas scala map

scala - son - tuplas append



Convierte una lista de tupla en un mapa(¿y lidias con una clave duplicada?) (7)

Estaba pensando en una buena forma de convertir una Lista de tuplas con la clave duplicada [("a","b"),("c","d"),("a","f")] en el mapa ("a" -> ["b", "f"], "c" -> ["d"]) . Normalmente (en python), crearía un mapa vacío y for-loop sobre la lista y verificaría la clave duplicada. Pero estoy buscando algo más scala-ish y una solución inteligente aquí.

Por cierto, el tipo real de clave-valor que uso aquí es (Int, Node) y quiero convertirme en un mapa de (Int -> NodeSeq)


Aquí hay otra alternativa:

x.groupBy(_._1).mapValues(_.map(_._2))


Aquí hay una forma más idiomática de Scala para convertir una lista de tuplas en un mapa que maneja claves duplicadas. Quieres usar un doblez

val x = List("a" -> "b", "c" -> "d", "a" -> "f") x.foldLeft(Map.empty[String, Seq[String]]) { case (acc, (k, v)) => acc.updated(k, acc.getOrElse(k, Seq.empty[String]) ++ Seq(v)) } res0: scala.collection.immutable.Map[String,Seq[String]] = Map(a -> List(b, f), c -> List(d))


Grupo y luego proyecto:

scala> val x = List("a" -> "b", "c" -> "d", "a" -> "f") //x: List[(java.lang.String, java.lang.String)] = List((a,b), (c,d), (a,f)) scala> x.groupBy(_._1).map { case (k,v) => (k,v.map(_._2))} //res1: scala.collection.immutable.Map[java.lang.String,List[java.lang.String]] = Map(c -> List(d), a -> List(b, f))

Una forma más escalada de usar fold, en la forma como there (omita map f step).


Para los Googlers que no esperan duplicados o que están de acuerdo con la política de manejo de duplicados predeterminada :

List("a" -> 1, "b" -> 2).toMap // Result: Map(a -> 1, c -> 2)

A partir del 2.12, la política predeterminada dice:

Las claves posteriores sobrescribirán las claves duplicadas: si se trata de una colección desordenada, la clave que está en el mapa resultante no está definida.


Para los Googlers que se preocupan por los duplicados:

implicit class Pairs[A, B](p: List[(A, B)]) { def toMultiMap: Map[A, List[B]] = p.groupBy(_._1).mapValues(_.map(_._2)) } > List("a" -> "b", "a" -> "c", "d" -> "e").toMultiMap > Map("a" -> List("b", "c"), "d" -> List("e"))


Puedes intentar esto

scala> val b = new Array[Int](3) // b: Array[Int] = Array(0, 0, 0) scala> val c = b.map(x => (x -> x * 2)) // c: Array[(Int, Int)] = Array((1,2), (2,4), (3,6)) scala> val d = Map(c : _*) // d: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 2 -> 4, 3 -> 6)


A continuación puede encontrar algunas soluciones. (GroupBy, FoldLeft, Aggregate, Spark)

val list: List[(String, String)] = List(("a","b"),("c","d"),("a","f"))

Variación GroupBy

list.groupBy(_._1).map(v => (v._1, v._2.map(_._2)))

Doble variación a la izquierda

list.foldLeft[Map[String, List[String]]](Map())((acc, value) => { acc.get(value._1).fold(acc ++ Map(value._1 -> List(value._2))){ v => acc ++ Map(value._1 -> (value._2 :: v)) } })

Variación agregada: similar a doblar a la izquierda

list.aggregate[Map[String, List[String]]](Map())( (acc, value) => acc.get(value._1).fold(acc ++ Map(value._1 -> List(value._2))){ v => acc ++ Map(value._1 -> (value._2 :: v)) }, (l, r) => l ++ r )

Variación de chispa - Para grandes conjuntos de datos (Conversión a un RDD y a un Mapa simple desde RDD)

import org.apache.spark.rdd._ import org.apache.spark.{SparkContext, SparkConf} val conf: SparkConf = new SparkConf().setAppName("Spark").setMaster("local") val sc: SparkContext = new SparkContext (conf) // This gives you a rdd of the same result val rdd: RDD[(String, List[String])] = sc.parallelize(list).combineByKey( (value: String) => List(value), (acc: List[String], value) => value :: acc, (accLeft: List[String], accRight: List[String]) => accLeft ::: accRight ) // To convert this RDD back to a Map[(String, List[String])] you can do the following rdd.collect().toMap