如何删除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;博士 除非你有充分的理由否则使用反向下降而不是反向.它出人意料地快速且令人惊讶地清晰. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |