Dada una cadena, quiero crear un mapa que para cada carácter de una cadena dé el número de veces que el carácter aparece en una cadena. La siguiente función hace un mapa de carácter a una lista de cadenas.

def wordOccurrences(w: String) = {
  val lower = w.toLowerCase.toList
  lower.groupBy(t => t)
}

Ahora quería modificar la última línea para:

lower.groupBy(t => t) map ( (x,y) => x -> y.length)

Pero no funciona, ¿alguien puede explicar por qué y cómo solucionarlo?

0
GraphLearner 21 feb. 2018 a las 16:02

2 respuestas

La mejor respuesta

Para propósitos de ping de map, un Map[K, V] es un Iterable[(K, V)] (observe el par adicional de paréntesis, que identifica un tipo de tupla), lo que significa que cuando map lo sobrepasa una función que va de (K, V) a su tipo de destino.

Sin embargo, lo que está haciendo es pasar una función que toma dos argumentos independientes , en lugar de un argumento de tupla única .

La diferencia se puede ver al inspeccionar los tipos de estas dos funciones en el shell de Scala:

scala> :t (a: Int, b: Int) => a + b
(Int, Int) => Int

scala> :t (p: (Int, Int)) => p._1 + p._2
((Int, Int)) => Int

Observe cómo el primero toma dos argumentos mientras que el segundo toma una sola tupla.

Lo que puede hacer es pasar una función que descomponga la tupla para que pueda vincular los componentes de la tupla de forma independiente:

lower.groupBy(t => t) map { case (x, y) => x -> y.length }

O alternativamente pasar una función que use la tupla sin deconstruirla

lower.groupBy(t => t) map (p => p._1 -> p._2.length)

Nota

Dotty, que es el proyecto actual del autor original de Scala en el que Martin Odersky está trabajando y que probablemente se convertirá en Scala 3, admite la sintaxis que está proponiendo, llamando a la característica adaptación de función aridad . Esto se ha discutido, junto con otras características, en el Keynote de 2016 de Odersky en Scala eXchange, "From DOT to Dotty" (aquí el video grabado en 2017 Voxxed Days CERN).

2
stefanobaghino 21 feb. 2018 a las 13:47

Puede usar

 lower.groupBy(t => t).mapValues(_.length)
2
Harald Gliebe 21 feb. 2018 a las 13:08