我对Scala很新,所以希望你能在这个问题中容忍这个问题,因为你觉得它很自然:)
我编写了一个函数,它使用yield语法返回一个Seq元素:
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方式”是什么?
答案 0 :(得分:8)
创建不同集合类型的有效方法是使用BashFAQ #24。它适用于import scala.collection.breakOut
val x: Map[String, Int] = (for (i <- 1 to 10) yield i.toString -> i)(breakOut)
s以及理解:
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)
}
x:Map [String,Int] = Map(8-&gt; 8,4-&gt; 4,9-&gt; 9,5-&gt; 5,10-&gt; 10,6-> 6, 1 - &gt; 1,2-&gt; 2,7-> 7,3-> 3)
在你的情况下它也应该有效:
toMap
与toMap
解决方案的比较:在Seq
创建Tuple2
Map
之前(在某些情况下偶然也可能是Map
)从中创建breakOut
,而Seq
省略此中间Map
创建并直接创建Seq
而不是中间#include<bitset>
#include<vector>
constexpr int Rows = 800000;
constexpr int Columns = 2048;
int your_function() {
std::vector<std::bitset<Columns> > data (Rows);
// do something with data
}
。
通常情况下,内存或CPU使用率(+ GC压力)并没有太大差异,但有时这些事情很重要。
答案 1 :(得分:5)
或者:
def calculateSomeMetrics(names: Seq[String]): Map[String, Long] = {
(for (name <- names) yield {
// Everything is the same as before
(name, metrics)
}).toMap
}
或者:
names.map { name =>
// doStuff
(name, metrics)
}.toMap
答案 2 :(得分:1)
这里有几个链接,或者是其他人指出的,或者我后来设法找到了,只是将它们组合在一个答案中供我将来参考。
breakOut
- Michał在his comment toMap
- this thread breakOut
如何运作的深刻解释 - 在this answer中
breakOut
is going away Karl