在groovy中,从列表中除去最后一项以外的所有项的最简洁的方法是什么?

在groovy中,从列表中除去最后一项以外的所有项的最简洁的方法是什么?,groovy,Groovy,我一直在试图找到一种简洁的方法来删除groovy中列表中除了最后一个元素以外的所有元素,但是我尝试过的所有事情似乎都有点过于复杂了。有没有更整洁的方法 失败:java.util.ConcurrentModificationException void removeAllButLastInPlace(list) { if(list.size() > 1) { def remove = list[0..-2] remove.each { list.rem

我一直在试图找到一种简洁的方法来删除groovy中列表中除了最后一个元素以外的所有元素,但是我尝试过的所有事情似乎都有点过于复杂了。有没有更整洁的方法

失败:
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([])