我一直试图找到一种巧妙的方法来删除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$SubList
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']
答案 0 :(得分:2)
而不是改变现有列表。为什么不返回新列表?
然后你就可以做到:
List removeAllButLast( List list ) {
list ? [list[-1]] : []
}
或者:
List removeAllButLastInPlace( List list ) {
list.drop( list.size() - 1 )
}
您也可以使用循环(如果必须有变异方法)
void removeAllButLastInPlace( List list ) {
while( list.size() > 1 ) list.remove( 0 )
}
答案 1 :(得分:0)
void removeAllButLastInPlace( List list ) {
def index = 0
list.reverse(true).retainAll({index++ == 0})
}
答案 2 :(得分:0)
我选择其中一个。我的标准是:a)按照要求修改清单(不返回新清单)和b)简洁。
然而,我已经使两个版本都返回对修改列表的引用,只是为了简化println
示例。您可以将返回类型设为“无效”状态。如果愿意,删除最后的' 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
除此之外:如果可能的话,我也会选择更具功能性的风格(即返回一个新的列表而不是修改现有的列表),除了那不是你要求的。无论如何,这是一个例子:
def lastAsList(xs) {
xs.isEmpty() ? [] : [xs[-1]]
}
println lastAsList([1, 2, 3])
println lastAsList([])