【问题标题】:What is the most efficient way to transform of seq of X to a seq of Y将 X 的序列转换为 Y 的序列的最有效方法是什么
【发布时间】:2021-12-28 03:24:03
【问题描述】:

我有一个 Seq 对象,例如 Seq(x1, x2, x3, x4),我想将其转换为 Seq(y1, y2, y3, y4)

这样做最有效的方法是什么

现在是我

val seq1 = Seq(x1, x2, x3......)
var seq2 = Seq[MyType2]()



for (myObj <- seq1) {
    seq2 = seq2 :+ myObj.tranformToType2
}

问题是 scala 文档说

https://www.scala-lang.org/api/2.12.x/scala/collection/Seq.html

由该序列的所有元素组成的新序列,后跟 elem。

所以我想知道将对象列表转换为另一个对象列表的最惯用/最有效的方法是什么

【问题讨论】:

  • 如果你关心性能那么不要使用Seq,因为它是一个你无法知道任何操作效率的接口。而是使用任何具体的集合,例如 ListVectorArraySeq 等。然后选择能够为您提供更适合您的代码的复杂性约束的集合。

标签: scala


【解决方案1】:

map 是您正在寻找的功能。详情请查看docs

一个简单的例子:

case class MyType1(x: String)
case class MyType2(x: Int)

val ls: Seq[MyType2] = Seq(MyType1("hello"), MyType1("world")).map(mt1 => MyType2(mt1.content.length))

【讨论】:

    【解决方案2】:

    您编写的代码是 Scala 命令式风格,但 Scala 旨在成为一种函数式语言。

    函数式方法是:

    val seq2 = seq1.map(myObj => myObj.tranformToType2)
    
    // Or shorter:
    val seq2 = seq1.map(_.tranformToType2)
    

    map 是函数编程中最有用的操作之一。您会发现,当您需要将某物转换为其他物时,您会在任何地方使用它。

    根据经验,每当您看到 varfor 循环时,这很臭,您应该问问自己我该如何以函数方式做到这一点

    【讨论】:

    • 跟进问题,在内部,地图是如何工作的?它是否分配了一个与原始数组大小相同的新数组并附加到它?为什么内部附加比 :+ 更有效
    • Seq 不是一个数组,它是一个序列的抽象接口,可以以多种不同的方式实现(ListVectorView 等)。由底层类型的实现决定如何最好地实现map,性能将取决于底层类型是什么。
    • 所以当我初始化一个 seq Seq(x1, x2, x3......) 时,什么是不可靠的支持数据结构?是链表还是索引数组?
    • 默认是List,它是不可变的链表。如果您认为性能在您的用例中至关重要,您可能想看看 stackoverflow.com/questions/10866639/… 并阅读不同实现的 Scaladoc。
    • 另外,map 可能不会比您的循环更有效在您描述您想做什么而不是如何做的意义上,它更符合习惯。
    猜你喜欢
    • 2011-05-29
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多