Colecciones de Scala: conjunto de arrayBy e índices de matriz de devolución para cada grupo
group-by scala-collections (3)
Aquí hay una versión con foldRight
. Creo que es razonablemente claro.
val a = Array("a", "c", "c", "z", "c", "b", "a")
a
.zipWithIndex
.foldRight(Map[String, List[Int]]())
{case ((e,i), m)=> m updated (e, i::m.getOrElse(e, Nil))}
//> res0: scala.collection.immutable.Map[String,List[Int]] = Map(a -> List(0, 6)
//| , b -> List(5), c -> List(1, 2, 4), z -> List(3))
Tengo una matriz, algo así:
val a = Array("a", "c", "c", "z", "c", "b", "a")
y quiero obtener un mapa con claves de todos los valores diferentes de esta matriz y valores con una colección de índices relevantes para cada grupo, es decir, para una matriz dada, la respuesta sería:
Map(
"a" -> Array(0, 6),
"b" -> Array(5),
"c" -> Array(1, 2, 4),
"z" -> Array(3)
)
Sorprendentemente, resultó ser algo más complicado de lo que había anticipado. Lo mejor que he llegado hasta ahora es:
a.zipWithIndex.groupBy {
case(cnt, idx) => cnt
}.map {
case(cnt, arr) => (cnt, arr.map {
case(k, v) => v
}
}
que no es ni conciso ni fácil de entender. Alguna mejor idea?
Otra versión que usa foldLeft
y un Map
inmutable con valor predeterminado:
val a = Array("a", "c", "c", "z", "c", "b", "a")
a.zipWithIndex.foldLeft(Map[String, List[Int]]().withDefaultValue(Nil))( (m, p) => m + ((p._1, p._2 +: m(p._1))))
// res6: scala.collection.immutable.Map[String,List[Int]] = Map(a -> List(6, 0), c -> List(4, 2, 1), z -> List(3), b -> List(5))
Su código puede ser reescrito como oneliner, pero se ve feo.
as.zipWithIndex.groupBy(_._1).mapValues(_.map(_._2))
Otra forma es usar mutable.MultiMap
import collection.mutable.{ HashMap, MultiMap, Set }
val as = Array("a", "c", "c", "z", "c", "b", "a")
val mm = new HashMap[String, Set[Int]] with MultiMap[String, Int]
y luego simplemente agregue todos los enlaces
as.zipWithIndex foreach (mm.addBinding _).tupled
//mm = Map(z -> Set(3), b -> Set(5), a -> Set(0, 6), c -> Set(1, 2, 4))
finalmente puedes convertirlo mm.toMap
si quieres una versión inmutable.