加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何删除Scala集合中的尾随元素?

发布时间:2020-12-16 18:27:12 所属栏目:安全 来源:网络整理
导读:假设我有一个看起来像这样的列表: List(0,5,34,9,0) 我想最终得到的是: List(0,9) 我正在删除所有尾随的零.有没有一种方法,比如: list.trimRight(_ == 0) 会做到这一点?我可以从头开始编写它,但在我看来,这是std集合中的东西吗? 我提出了: list.take(l
假设我有一个看起来像这样的列表:

List(0,5,34,9,0)

我想最终得到的是:

List(0,9)

我正在删除所有尾随的零.有没有一种方法,比如:

list.trimRight(_ == 0)

会做到这一点?我可以从头开始编写它,但在我看来,这是std集合中的东西吗?

我提出了:

list.take(list.lastIndexWhere(_ != 0) + 1)

有更好的方法吗?

解决方法

如果你想知道哪个是最优雅的,那么我会说

list.reverse.dropWhile(_ == 0).reverse

因为它只需要引用一次输入,意图非常明确.

如果您想知道哪个是最有效的,您需要做一些基准测试.结果(对于您的简短测试列表)可能会让您感到惊讶!

// Slowest
191 ns     dhg's EnhancedSeq
173 ns     user unknown's custom dropRight
 91 ns     andyczerwonka's take/lastIndexWhere
 85 ns     Rex's : (foldRight) -- see below
 60 ns     dhg / Daniel's reverse/dropWhile/reverse
 52 ns     Rex's customDropTrailingZeros -- see below
// Fastest

可能存在一些适度的机器到机器的差异,但基本上这是一种情况,对于简短的列表,花哨并没有帮助你.很长的列表可能会发生很大的变化.

这是折叠版本(但是大型列表上的堆栈溢出):

(list : list.take(0)){ (x,ys) => if (x==0 && ys.isEmpty) ys else x :: ys }

这是自定义版本(完全非通用 – 仅适用于此特定任务!):

@annotation.tailrec def customDropZeros(
  xs: List[Int],buffer: Array[Int] = new Array[Int](16),n: Int = 0
): List[Int] = {
  if (xs.isEmpty) {
    var ys = xs
    var m = n
    while (m>0 && buffer(m-1)==0) m -= 1
    var i = m-1
    while (i>=0) {
      ys = buffer(i) :: ys
      i -= 1
    }
    ys
  }
  else {
    val b2 = (
      if (n<buffer.length) buffer
      else java.util.Arrays.copyOf(buffer,buffer.length*2)
    )
    b2(n) = xs.head
    customDropZeros(xs.tail,b2,n+1)
  }
}

TL;博士

除非你有充分的理由否则使用反向下降而不是反向.它出人意料地快速且令人惊讶地清晰.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读