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

标签 scala dictionary yield seq

我对 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/

相关文章:

java - 运行同时包含 Scala 代码的 Java 程序的最佳方式是什么?

scala - 处理 future 和选择的干净方式

java - scala 和 java 枚举之间的区别

python - 使用类属性访问字典

python - 如何反转字典项并列出按公共(public)值分组的键

java - stackoverflow异常的原因是什么?

python - 这个 Python 脚本可以改进吗?

javascript - ES6 生成器机制 - 传递给 next() 的第一个值去哪里了?

scala - 使用 JDBC 创建 PostgreSQL 触发器

python - 在输入不变的情况下在python中生成连续数字