Vas*_*kin 2 dictionary scala yield seq
我是Scala的新手,所以希望你能在这个问题中容忍这个问题,如果你发现它是noobish :)
我写了一个函数,它使用yield语法返回一个Seq元素:
def calculateSomeMetrics(names: Seq[String]): Seq[Long] = {
for (name <- names) yield {
// some auxiliary actions
val metrics = somehowCalculateMetrics()
metrics
}
}
Run Code Online (Sandbox Code Playgroud)
现在我需要修改它以返回Map以保留原始名称对每个计算值:
def calculateSomeMetrics(names: Seq[String]): Map[String, Long] = { ... }
Run Code Online (Sandbox Code Playgroud)
我试图使用相同的yield语法,但产生一个元组而不是单个元素:
def calculateSomeMetrics(names: Seq[String]): Map[String, Long] = {
for (name <- names) yield {
// Everything is the same as before
(name, metrics)
}
}
Run Code Online (Sandbox Code Playgroud)
但是,编译器会Seq[(String, Long)]根据编译器错误消息对其进行解释
type mismatch;
found : Seq[(String, Long)]
required: Map[String, Long]
Run Code Online (Sandbox Code Playgroud)
所以我想知道,实现这样的事情的"规范Scala方式"是什么?
创建不同集合类型的有效方法是使用scala.collection.breakOut.它既适用于Maps,也适用于理解:
import scala.collection.breakOut
val x: Map[String, Int] = (for (i <- 1 to 10) yield i.toString -> i)(breakOut)
Run Code Online (Sandbox Code Playgroud)
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)
}
Run Code Online (Sandbox Code Playgroud)
比较与toMap解决方案:之前toMap创建一个中间Seq的Tuple2S(这亦可能是Map在某些情况下也是如此),并从它创建的Map,而breakOut省略了这中间Seq的创建和创建Map的,而不是直接在中间Seq.
通常这不是内存或CPU使用量(+ GC压力)的巨大差异,但有时这些事情很重要.
或者:
def calculateSomeMetrics(names: Seq[String]): Map[String, Long] = {
(for (name <- names) yield {
// Everything is the same as before
(name, metrics)
}).toMap
}
Run Code Online (Sandbox Code Playgroud)
要么:
names.map { name =>
// doStuff
(name, metrics)
}.toMap
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
454 次 |
| 最近记录: |