在groovy中,从列表中除去最后一项以外的所有项的最简洁的方法是什么?
我一直在试图找到一种简洁的方法来删除groovy中列表中除了最后一个元素以外的所有元素,但是我尝试过的所有事情似乎都有点过于复杂了。有没有更整洁的方法 失败:在groovy中,从列表中除去最后一项以外的所有项的最简洁的方法是什么?,groovy,Groovy,我一直在试图找到一种简洁的方法来删除groovy中列表中除了最后一个元素以外的所有元素,但是我尝试过的所有事情似乎都有点过于复杂了。有没有更整洁的方法 失败:java.util.ConcurrentModificationException void removeAllButLastInPlace(list) { if(list.size() > 1) { def remove = list[0..-2] remove.each { list.rem
java.util.ConcurrentModificationException
void removeAllButLastInPlace(list) {
if(list.size() > 1) {
def remove = list[0..-2]
remove.each { list.remove(it) }
}
}
失败:java.lang.CloneNotSupportedException:java.util.ArrayList$子列表
void removeAllButLastInPlace(list) {
if(list.size() > 1) {
def remove = list[0..-2].clone()
remove.each { list.remove(it) }
}
}
工作,但清单建设似乎没有必要
void removeAllButLastInPlace(list) {
if(list.size() > 1) {
def remove = [] + list[0..-2]
remove.each { list.remove(it) }
}
}
虽然有效,但似乎有点神秘
void removeAllButLastInPlace(list) {
(list.size() - 1).times { list.remove(0) }
}
有效,也许最“正确”
void removeAllButLastInPlace(list) {
list.retainAll { list.lastIndexOf(it) == list.size() - 1 }
}
代码应完成以下测试:
list = []
removeAllButLastInPlace(list)
assert list == []
list = ['a']
removeAllButLastInPlace(list)
assert list == ['a']
list = ['a', 'b']
removeAllButLastInPlace(list)
assert list == ['b']
list = ['a', 'b', 'c']
removeAllButLastInPlace(list)
assert list == ['c']
与其修改现有列表,为什么不返回新列表 然后你可以简单地做:
List removeAllButLast( List list ) {
list ? [list[-1]] : []
}
或:
编辑:
您还可以使用循环(如果必须使用变异方法)
我想买一个。我的标准是a)按照您的要求修改列表(不返回新列表)和b)简洁 然而,为了简化
println
示例,我让两个版本都返回对修改列表的引用。如果愿意,可以将返回类型设为“void”,并从每个返回类型中删除最后一行“xs”
def xs1 = [1, 2, 3, 4, 5]
def xs2 = [9]
def xs3 = []
def keepOnlyLast1(xs) {
while(xs.size() > 1) xs.remove(0)
xs
}
def keepOnlyLast2(xs) {
xs[0 ..< xs.size()-1] = []
xs
}
println "Version 1"
println keepOnlyLast1([] + xs1)
println keepOnlyLast1([] + xs2)
println keepOnlyLast1([] + xs3)
println "Version 2"
println keepOnlyLast2([] + xs1)
println keepOnlyLast2([] + xs2)
println keepOnlyLast2([] + xs3)
/* Sanity check that these methods *really* modify the list. */
println "Sanity Check"
keepOnlyLast1(xs1)
println xs1
keepOnlyLast2(xs2)
println xs2
如果列表中包含重复项,则此操作将失败,而现在只需反转列表(
take
不会改变列表,因此只返回一个包含单个元素的新列表,该元素将被上述方法丢弃)是的,我知道这一点。在这个特定的实例中,我特别想修改列表实例。很公平,只要您知道它可能会降低代码的并发性。我知道并且很满意这一点-这个特定的代码用于shell脚本。好的。虽然当代码是不可变的时,它通常会更整洁。祝你玩得开心。谢谢,这是一个有用的注释(整洁和并发)。但在这种特殊情况下,重新分配引用是不可能的。否决票是为了什么?我没有足够的代表来否决票,但可能是因为你没有感谢那些试图帮助你的人。
void removeAllButLastInPlace( List list ) {
while( list.size() > 1 ) list.remove( 0 )
}
void removeAllButLastInPlace( List list ) {
def index = 0
list.reverse(true).retainAll({index++ == 0})
}
def xs1 = [1, 2, 3, 4, 5]
def xs2 = [9]
def xs3 = []
def keepOnlyLast1(xs) {
while(xs.size() > 1) xs.remove(0)
xs
}
def keepOnlyLast2(xs) {
xs[0 ..< xs.size()-1] = []
xs
}
println "Version 1"
println keepOnlyLast1([] + xs1)
println keepOnlyLast1([] + xs2)
println keepOnlyLast1([] + xs3)
println "Version 2"
println keepOnlyLast2([] + xs1)
println keepOnlyLast2([] + xs2)
println keepOnlyLast2([] + xs3)
/* Sanity check that these methods *really* modify the list. */
println "Sanity Check"
keepOnlyLast1(xs1)
println xs1
keepOnlyLast2(xs2)
println xs2
def lastAsList(xs) {
xs.isEmpty() ? [] : [xs[-1]]
}
println lastAsList([1, 2, 3])
println lastAsList([])