如何直接使用scala.collection.immutable.Map的API和?

时间:2016-12-15 03:15:59

标签: scala

我想总结Map("one" -> 2, "two" -> 3, "three" -> 4)的值2+3+4,当然我可以使用以下方法:

  1. Map("one" -> 2, "two" -> 3, "three" -> 4).foldLeft(0)(_ + _._2)
  2. Map("one" -> 2, "two" -> 3, "three" -> 4).values.sum()
  3. 我发现Map还有另一个更直接的API总和:def sum: A,但是,我不会搜索有关此API的任何示例,如何使用它?

2 个答案:

答案 0 :(得分:3)

对于sum[B >: (A, B)](implicit num: Numeric[B]): B,如您所见,它需要implicit参数,参数类型为Numeric[B]类型。

  

Scala Numerictrait,定义了一系列数学运算。   http://www.scala-lang.org/api/current/scala/math/Numeric.html

对于您的情况,类型为Map[String, Int],因此您需要为implicit方法Numeric[(String, Int)]实施sum,例如:

 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))

如上面的代码所示,我们使用Numeric实现了自己的(String, Int)类型,并实现了方法。

我们implicit将此问题纳入我们的范围,因此我们可以使用implicitly获取function并致电。

sum方法也可以找到implicit的{​​{1}}参数

答案 1 :(得分:2)

Map.sum方法不能做你想要的 - 你的功能看起来很好。

Map具有sum方法的原因是所有 TraversableOnce类都有一个sum方法,只有在集合类型为数字时才有效。但是,Map[K, V]TraversableOnce[(K, V)],因此这种方法不起作用(键值元组不是数字类型)。