如何使用 A 的值作为映射中的键将 Seq[A] 转换为 Map[Int, A]?

发布于 2024-09-03 06:05:59 字数 335 浏览 3 评论 0原文

我有一个包含类对象的 Seq ,如下所示:

class A (val key: Int, ...)

现在我想使用 将此 Seq 转换为 Map >key 每个对象的值作为键,对象本身作为值。那么:

val seq: Seq[A] = ...
val map: Map[Int, A] = ... // How to convert seq to map?

如何在 Scala 2.8 中高效且优雅地完成此操作?

I have a Seq containing objects of a class that looks like this:

class A (val key: Int, ...)

Now I want to convert this Seq to a Map, using the key value of each object as the key, and the object itself as the value. So:

val seq: Seq[A] = ...
val map: Map[Int, A] = ... // How to convert seq to map?

How can I does this efficiently and in an elegant way in Scala 2.8?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

惜醉颜 2024-09-10 06:05:59

由于 2.8 Scala 已经有了 .toMap,所以:

val map = seq.map(a => a.key -> a).toMap

或者如果您热衷于避免构造元组的中间序列,那么在 Scala 2.8 到 2.12 中:

val map: Map[Int, A] = seq.map(a => a.key -> a)(collection.breakOut)

或者在 Scala 2.13 和 3 中(它们不这样做)没有 breakOut,但有可靠的 .view):

val map = seq.view.map(a => a.key -> a).toMap

Since 2.8 Scala has had .toMap, so:

val map = seq.map(a => a.key -> a).toMap

or if you're gung ho about avoiding constructing an intermediate sequence of tuples, then in Scala 2.8 through 2.12:

val map: Map[Int, A] = seq.map(a => a.key -> a)(collection.breakOut)

or in Scala 2.13 and 3 (which don't have breakOut, but do have a reliable .view):

val map = seq.view.map(a => a.key -> a).toMap
别闹i 2024-09-10 06:05:59

映射您的 Seq 并生成元组序列。然后使用这些元组创建一个Map。适用于所有版本的 Scala。

val map = Map(seq map { a => a.key -> a }: _*)

Map over your Seq and produce a sequence of tuples. Then use those tuples to create a Map. Works in all versions of Scala.

val map = Map(seq map { a => a.key -> a }: _*)
花辞树 2024-09-10 06:05:59

另外一个 2.8 变体,为了更好的措施,也很高效:

scala> case class A(key: Int, x: Int)
defined class A

scala> val l = List(A(1, 2), A(1, 3), A(2, 1))
l: List[A] = List(A(1,2), A(1,3), A(2,1))

scala> val m: Map[Int, A] = (l, l).zipped.map(_.key -> _)(collection.breakOut)
m: Map[Int,A] = Map((1,A(1,3)), (2,A(2,1)))

请注意,如果您有重复的键,您将在地图创建过程中丢弃其中一些!您可以使用 groupBy 创建一个映射,其中每个值都是一个序列:

scala> l.groupBy(_.key)
res1: scala.collection.Map[Int,List[A]] = Map((1,List(A(1,2), A(1,3))), (2,List(A(2,1))))

One more 2.8 variation, for good measure, also efficient:

scala> case class A(key: Int, x: Int)
defined class A

scala> val l = List(A(1, 2), A(1, 3), A(2, 1))
l: List[A] = List(A(1,2), A(1,3), A(2,1))

scala> val m: Map[Int, A] = (l, l).zipped.map(_.key -> _)(collection.breakOut)
m: Map[Int,A] = Map((1,A(1,3)), (2,A(2,1)))

Note that if you have duplicate keys, you'll discard some of them during Map creation! You could use groupBy to create a map where each value is a sequence:

scala> l.groupBy(_.key)
res1: scala.collection.Map[Int,List[A]] = Map((1,List(A(1,2), A(1,3))), (2,List(A(2,1))))
清风挽心 2024-09-10 06:05:59

正如 scala 知道将两个元组转换为映射一样,您首先需要将 seq 转换为元组,然后映射 so(如果它是 int,在我们的例子中是 string,string 也没关系):

一般算法是this:

  1. 对于 Seq Item 中的每个项目
  2. --> Tuple(key, value)
  3. 对于每个tuple(key, value)
  4. 聚合到Map(key,value)

或者总结:

步骤1:Seq -->两个元组

步骤2:两个元组-->地图

示例:

case class MyData(key: String, value: String) // One item in seq to be converted to a map entry.

// Our sequence, simply a seq of MyData
val myDataSeq = Seq(MyData("key1", "value1"), MyData("key2", "value2"), MyData("key3", "value3")) // List((key1,value1), (key2,value2), (key3,value3))

// Step 1: Convert seq to tuple
val myDataSeqAsTuple = myDataSeq.map(myData => (myData.key, myData.value)) // List((key1,value1), (key2,value2), (key3,value3))

// Step 2: Convert tuple of two to map.
val myDataFromTupleToMap = myDataSeqAsTuple.toMap // Map(key1 -> value1, key2 -> value2, key3 -> value3)

As scala knows to convert a Tuple of two to a map, you would first want to convert your seq to a tuple and then to map so (doesn't matter if it's int, in our case string, string):

The general algorithm is this:

  1. For each item in Seq
  2. Item --> Tuple(key, value)
  3. For each tuple(key, value)
  4. Aggregate to Map(key,value)

Or to sum up:

Step 1: Seq --> Tuple of two

Step 2: Tuple of two --> Map

Example:

case class MyData(key: String, value: String) // One item in seq to be converted to a map entry.

// Our sequence, simply a seq of MyData
val myDataSeq = Seq(MyData("key1", "value1"), MyData("key2", "value2"), MyData("key3", "value3")) // List((key1,value1), (key2,value2), (key3,value3))

// Step 1: Convert seq to tuple
val myDataSeqAsTuple = myDataSeq.map(myData => (myData.key, myData.value)) // List((key1,value1), (key2,value2), (key3,value3))

// Step 2: Convert tuple of two to map.
val myDataFromTupleToMap = myDataSeqAsTuple.toMap // Map(key1 -> value1, key2 -> value2, key3 -> value3)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文