我可以使用for-yield语法在Scala中返回Map集合吗?

时间:2017-11-29 13:02:03

标签: scala dictionary yield seq

我对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方式”是什么?

3 个答案:

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

这里有几个链接,或者是其他人指出的,或者我后来设法找到了,只是将它们组合在一个答案中供我将来参考。

相关问题