【问题标题】:Idiomatic way to prepend list to another list in Scala在 Scala 中将列表添加到另一个列表的惯用方法
【发布时间】:2015-02-14 19:46:48
【问题描述】:

抱歉这个新手问题,但我在 Scala 中找不到这个问题的简写。

val s1 = List(8, 9, 10)
val s2 = List(7, 6, 5)
val s12 = s2.foldLeft(s1)((acc, x) => x :: acc)
assert(s12 === List(5, 6, 7, 8, 9, 10))

我应该使用哪个运算符来达到相同的效果?

【问题讨论】:

    标签: scala


    【解决方案1】:

    您可以反转第二个列表并将结果添加到第一个列表

    val s12 = s2.reverse ::: s1
    

    有关可用方法的其他文档,请参阅scala.collection.immutable.List APIdocs

    例如:::

    在该列表前面添加给定列表的元素。

    顺便说一句,::: 像这样使用(中缀符号 - 不带点)是 right-associative(这意味着该方法将在正确的对象上调用 - 在这种情况下为 s1)。
    此外,当使用点符号调用::: 时,它会在点左侧的对象上调用,所以在这种情况下s2.reverse.:::(s1) 将导致List(8, 9, 10, 5, 6, 7)

    【讨论】:

    • 据我了解,这有点低效。我发现 xs reverse_::: ys 根据 API 文档“更高效”,但它看起来有点难看..
    • @BasilTomato 如果您谈论的是数量有限且数量有限的项目,那么我每次都会选择美学而不是性能。如果它是大量或无限数量的项目,并且您真的担心性能,您可以选择更复杂的数据结构,如 Vector 并使用它的reverseIterator 按您想要的顺序访问每个项目。
    • @BasilTomato xs reverse_::: ys 看起来很有趣。它的 API 文档在哪里?
    • @acjay:我猜,有效地扭转它两次感觉不对。
    【解决方案2】:

    也可以这样写:

    s2 reverse_::: s1
    

    s2.reverse ::: s1 更高效(API 文档中也指出了这一点)。

    也可以这样写:

    (s1 /: s2)(_.::(_))
    

    再想一想,也许s2.foldLeft(s1)((acc, x) => x :: acc) 并没有那么糟糕。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-13
      • 2021-08-18
      • 2018-03-06
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      相关资源
      最近更新 更多