Quiero sumar los valores de Map("one" -> 2, "two" -> 3, "three" -> 4) 2+3+4, por supuesto que puedo usar los siguientes métodos:

  1. Map("one" -> 2, "two" -> 3, "three" -> 4).foldLeft(0)(_ + _._2)
  2. Map("one" -> 2, "two" -> 3, "three" -> 4).values.sum()

Descubrí que Map tiene otra suma de API más directa: def sum: A, pero no busco ningún ejemplo sobre esto API, ¿cómo se usa?

2
abelard2008 15 dic. 2016 a las 06:15

2 respuestas

La mejor respuesta

Para sum[B >: (A, B)](implicit num: Numeric[B]): B, como puede ver, necesita el parámetro implicit y el tipo de parámetro es Numeric[B].

Scala Numeric es trait que definió una serie de operaciones matemáticas. http://www.scala-lang.org/api/ current / scala / math / Numeric.html

Para su caso, el tipo es Map[String, Int], por lo que debe implementar el método implicit para Numeric[(String, Int)] para sum, como:

 trait MyTupleNumeric extends Numeric[(String, Int)] {
    def plus(x: (String, Int), y: (String, Int)) = ("", x._2 + y._2)

    override def minus(x: (String, Int), y: (String, Int)): (String, Int) = ("", x._2 - x._2)

    override def times(x: (String, Int), y: (String, Int)): (String, Int) = ("", x._2 * y._2)

    override def negate(x: (String, Int)): (String, Int) = ("", -x._2)

    override def fromInt(x: Int): (String, Int) = ("", x)

    override def toInt(x: (String, Int)): Int = x._2

    override def toLong(x: (String, Int)): Long = x._2.toLong

    override def toFloat(x: (String, Int)): Float = x._2.toFloat

    override def toDouble(x: (String, Int)): Double = x._2.toDouble

    override def compare(x: (String, Int), y: (String, Int)): Int = x._2 - y._2
  }

  implicit object MyTupleNumericImplicit extends MyTupleNumeric

  val f = implicitly[Numeric[(String, Int)]] // implicitly is used find implicits base on the type
  println(f.plus(("one", 2), ("two", 3)))
  val r = Map("one" -> 2, "two" -> 3, "three" -> 4)
  println(r.sum._2)
  println(r.sum(MyTupleNumericImplicit))

Como el código anterior, hemos implementado nuestro propio tipo Numeric con (String, Int), e implementamos métodos.

Y implicit lo incluimos en nuestro alcance, por lo que podemos usar implicitly para obtener el function y llamar.

Y el método sum también podría encontrar el parámetro implicit para Numeric[(String, Int)]

3
chengpohi 15 dic. 2016 a las 06:00

El método Map.sum no hace lo que usted desea: sus funciones se ven bien tal como están.

La razón por la que Map tiene un método de suma es que todas TraversableOnce tienen un método de suma, que solo funciona si el tipo de colección es numérico. Sin embargo, un Map[K, V] es un TraversableOnce[(K, V)], por lo que este enfoque no funcionará (la tupla clave-valor no es un tipo numérico).

2
Tim 15 dic. 2016 a las 03:58