如果我有这个:
def array = [1,2,3,4,5,6]
是否有一些内置允许我这样做(或类似的东西):
array.split(2)
并得到:
[[1,2],[3,4],[5,6]]
?
编辑从 groovy 1.8.6 开始,您可以在列表上使用 collat e方法
def origList = [1, 2, 3, 4, 5, 6, 7, 8, 9]
assert [[1, 2, 3, 4], [5, 6, 7, 8], [9]] == origList.collate(4)
另一种使用注入和元类的方法
List.metaClass.partition = { size ->
def rslt = delegate.inject( [ [] ] ) { ret, elem ->
( ret.last() << elem ).size() >= size ? ret << [] : ret
}
if( rslt.last()?.size() == 0 ) rslt.pop()
rslt
}
def origList = [1, 2, 3, 4, 5, 6]
assert [ [1], [2], [3], [4], [5], [6] ] == origList.partition(1)
assert [ [1, 2], [3, 4], [5, 6] ] == origList.partition(2)
assert [ [1, 2, 3], [4, 5, 6] ] == origList.partition(3)
assert [ [1, 2, 3, 4], [5, 6] ] == origList.partition(4)
assert [ [1, 2, 3, 4, 5], [6] ] == origList.partition(5)
assert [ [1, 2, 3, 4, 5, 6] ] == origList.partition(6)
assert [ ] == [ ].partition(2)
编辑:修复了空列表的问题
我同意 Chris 的观点,即 groovy 没有内置任何东西来处理这个问题(至少对于超过 2 个分区),但我将你的问题解释为问的问题与他所做的不同。这是一个实现我认为您要求的实现:
def partition(array, size) {
def partitions = []
int partitionCount = array.size() / size
partitionCount.times { partitionNumber ->
def start = partitionNumber * size
def end = start + size - 1
partitions << array[start..end]
}
if (array.size() % size) partitions << array[partitionCount * size..-1]
return partitions
}
def origList = [1, 2, 3, 4, 5, 6]
assert [[1], [2], [3], [4], [5], [6]] == partition(origList, 1)
assert [[1, 2], [3, 4], [5, 6]] == partition(origList, 2)
assert [[1, 2, 3], [4, 5, 6]] == partition(origList, 3)
assert [[1, 2, 3, 4], [5, 6]] == partition(origList, 4)
assert [[1, 2, 3, 4, 5], [6]] == partition(origList, 5)
assert [[1, 2, 3, 4, 5, 6]] == partition(origList, 6)
查看 groovy 1.8.6。List 上有一个新的 collate 方法。
def list = [1, 2, 3, 4]
assert list.collate(4) == [[1, 2, 3, 4]] // gets you everything
assert list.collate(2) == [[1, 2], [3, 4]] //splits evenly
assert list.collate(3) == [[1, 2, 3], [4]] // won't split evenly, remainder in last list.
查看Groovy List 文档以获取更多信息,因为还有一些其他参数可以为您提供一些其他选项,包括删除其余部分。
没有内置的东西可以做到这一点,但不难写:
def array = [1,2,3,4,5,6]
int mid = (int) (array.size() / 2)
def left = array[0..mid-1]
def right = array[mid..array.size()-1]
println left
println right
这是一个替代版本,它使用 Groovy 的动态特性向 List 类添加一个 split 方法,它可以满足您的期望:
List.metaClass.split << { size ->
def result = []
def max = delegate.size() - 1
def regions = (0..max).step(size)
regions.each { start ->
end = Math.min(start + size - 1, max)
result << delegate[start..end]
}
return result
}
def original = [1, 2, 3, 4, 5, 6]
assert [[1, 2], [3, 4], [5, 6]] == original.split(2)
我知道这已经很老了——但是对于那些希望将列表分成相等的分区(有余数)的人来说,你错过了 Tim 对原始帖子的评论,最新的常规方法是 List 对象的 collate() 方法从 Groovy 1.8.6 开始可用。
def array = [1, 2, 3, 4, 5, 6, 7]
assert [[1], [2], [3], [4], [5], [6], [7]] == array.collate(1, 1, true)
assert [[1, 2], [3, 4], [5, 6], [7]] == array.collate(2, 2, true)
assert [[1, 2, 3], [4, 5, 6], [7]] == array.collate(3, 3, true)
assert [[1, 2, 3, 4], [5, 6, 7]] == array.collate(4, 4, true)
assert [[1, 2, 3, 4, 5], [6, 7]] == array.collate(5, 5, true)
assert [[1, 2, 3, 4, 5, 6], [7]] == array.collate(6, 6, true)
assert [[1, 2, 3, 4, 5, 6, 7]] == array.collate(7, 7, true)
List.metaClass.split << { step ->
def result = [], max = delegate.size(), min = 0
while(min+step < max){
result.add delegate.subList(min,min+=step)
}
result.add delegate.subList(min, max)
result
}
这个问题很老,但无论如何我想分享我想出的将列表拆分为相同大小的列表的方法。
list.collate
很棒,但对我不起作用,因为我需要将列表平均拆分。
我在哪里做什么:
class PartitionCategory {
static evenlyPartitionWithCount(Collection self, int count) {
def indexes = 0..<self.size()
def sizes = indexes.countBy({ i -> i % count }).values()
def ranges = sizes.inject([]) { a, v -> a << (a ? (a.last().last() + 1)..(a.last().last() + v) : 0..<v) }
ranges.collect { r -> self[r] }
}
static evenlyPartitionWithSize(Collection self, int size) {
self.evenlyPartitionWithCount((int) Math.ceil(self.size() / size))
}
}
def array = [1, 2, 3, 4, 5, 6, 7]
use (PartitionCategory) {
assert [[1], [2], [3], [4], [5], [6], [7]] == array.evenlyPartitionWithSize(1)
assert [[1, 2], [3, 4], [5, 6], [7]] == array.evenlyPartitionWithSize(2)
assert [[1, 2, 3], [4, 5], [6, 7]] == array.evenlyPartitionWithSize(3)
assert [[1, 2, 3, 4], [5, 6, 7]] == array.evenlyPartitionWithSize(4)
assert [[1, 2, 3, 4], [5, 6, 7]] == array.evenlyPartitionWithSize(5)
assert [[1, 2, 3, 4], [5, 6, 7]] == array.evenlyPartitionWithSize(6)
assert [[1, 2, 3, 4, 5, 6, 7]] == array.evenlyPartitionWithSize(7)
}