从 Map [Scala] 中获取某些键的值总和

Fetch the sum of values for certain keys from a Map [Scala]

如何以更高效和优化的方式从映射中获取某些键的值之和?

例如:

var myMap = "SOSSPSSQSSOR".groupBy(identity).mapValues(_.size).toMap
>>myMap: scala.collection.immutable.Map[Char,Int] = Map(Q -> 1, P -> 1, R -> 1, O -> 2, S -> 7)

myMap.sumExcludingValuesFor("S,O")

def sumExcludingValuesFor(s:String):Int = {
//return the sum of the values for keys except S, O
}

到目前为止我的实施:

var charMap = "SOSSPSSQSSOR".toString.groupBy(identity).mapValues(_.size).toMap
var excludeChar = Set('S','O')
var mapExcludingSO = charMap.filterKeys { excludeChar.contains(_) == false }
println(mapOnlySO.values.toList.sum)

但正在寻找比这更好的实现。

非常感谢任何帮助!

一旦你隔离了感兴趣的键,而不是用它们构建一个新的 Map,使用它们直接访问要求和的值。

val charMap = "SOSSPSSQSSOR".groupBy(identity).mapValues(_.length)
charMap.keySet.diff("SO".toSet).foldLeft(0)(_ + myMap(_)) // res0: Int = 3

您的实施没有问题。您可能可以通过消除中间集合以及一些不必要的遍历和键查找来获得边际改进,但这对于几乎所有实际目的来说都是矫枉过正:

input
  .groupBy(identity)
  .foldLeft(0) { 
     case (s, ("S"|"O", _)) => s
     case (s, (_, v)) => s + v.size
  }

一个经常被忽视的事实是,您可以将 Scala 集合用作函数。

  • Seq[A]Int => A(部分,按索引)
  • Set[A]A => Boolean(成员资格检查)
  • Map[K, V]K => V(部分)

允许你写:

myMap.keysIterator.filterNot("SO".toSet).map(myMap).sum

它还将避免中间集合,基于Iterator