我对 Scala 还很陌生,所以希望你能容忍这个问题,以防你觉得这个问题很菜鸟:)
我编写了一个使用yield语法返回元素序列的函数:
def calculateSomeMetrics(names: Seq[String]): Seq[Long] = {
for (name <- names) yield {
// some auxiliary actions
val metrics = somehowCalculateMetrics()
metrics
}
}
现在我需要修改它以返回一个 Map,以针对每个计算值保留原始名称:
def calculateSomeMetrics(names: Seq[String]): Map[String, Long] = { ... }
我尝试使用相同的yield语法,但生成一个元组而不是单个元素:
def calculateSomeMetrics(names: Seq[String]): Map[String, Long] = {
for (name <- names) yield {
// Everything is the same as before
(name, metrics)
}
}
但是,编译器根据编译器错误消息解释它Seq[(String, Long)]
type mismatch;
found : Seq[(String, Long)]
required: Map[String, Long]
所以我想知道,实现这样的事情的“规范的 Scala 方式”是什么?
最佳答案
创建不同集合类型的有效方法是使用 scala.collection.breakOut
。它可以与 Map
一起使用,也可以用于理解:
import scala.collection.breakOut
val x: Map[String, Int] = (for (i <- 1 to 10) yield i.toString -> i)(breakOut)
x: Map[String,Int] = Map(8 -> 8, 4 -> 4, 9 -> 9, 5 -> 5, 10 -> 10, 6 -> 6, 1 -> 1, 2 -> 2, 7 -> 7, 3 -> 3)
在你的情况下它也应该有效:
import scala.collection.breakOut
def calculateSomeMetrics(names: Seq[String]): Map[String, Long] = {
(for (name <- names) yield {
// Everything is the same as before
(name, metrics)
})(breakOut)
}
与 toMap
解决方案的比较:在 toMap
创建 Tuple2
的中间 Seq
之前(顺便说一句,这可能是在某些情况下也是一个 Map
),并从中创建 Map
,而 breakOut
忽略这个中间的 Seq
创建并直接创建 Map
而不是中间的 Seq
。
通常这在内存或 CPU 使用率(+ GC 压力)方面并不是一个巨大的差异,但有时这些事情很重要。
关于scala - 我可以使用 for-yield 语法返回 Scala 中的 Map 集合吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47553534/