list 如何在 Groovy 中将列表拆分为大小相等的列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2924395/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 01:30:37  来源:igfitidea点击:

How to split a list into equal sized lists in Groovy?

listgroovybuilt-in

提问by Geo

If I have this:

如果我有这个:

def array = [1,2,3,4,5,6]

Is there some built-in which allows me to do this ( or something similar ):

是否有一些内置功能可以让我这样做(或类似的东西):

array.split(2)

and get:

并得到:

[[1,2],[3,4],[5,6]]

?

?

采纳答案by Ted Naleid

I agree with Chris that there isn't anything built into groovy to handle this (at least for more than 2 partitions), but I interpreted your question to be asking something different than he did. Here's an implementation that does what I think you're asking for:

我同意 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)

回答by tim_yates

EDITAs of groovy 1.8.6 you can use the collatemethod on lists

编辑从 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)


Another method using inject and metaClasses

另一种使用注入和元类的方法

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)

Edit: fixed an issue with the empty list

编辑:修复了空列表的问题

回答by benkiefer

Check out groovy 1.8.6. There is a new collate method on List.

查看 groovy 1.8.6。List 上有一个新的 collat​​e 方法。

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.

Take a look at the Groovy List documentationfor more info because there are a couple of other params that give you some other options, including dropping the remainder.

查看Groovy List 文档以获取更多信息,因为还有一些其他参数可以为您提供一些其他选项,包括删除其余部分。

回答by Paresh

I was looking for the same problem and I found the collate()method for lists to be very useful.

我一直在寻找同样的问题,我发现collate()列表的方法非常有用。

array.collate(2)

Hereis the link to the documentation.

是文档的链接。

回答by Chris Dail

There is nothing builtin to do that but it is not hard to write:

没有任何内置功能可以做到这一点,但编写起来并不难:

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

回答by Christoph Metzendorf

Here's an alternative version, that uses Groovy's dynamic features to add a split method to the List class, that does what you expect:

这是一个替代版本,它使用 Groovy 的动态特性将 split 方法添加到 List 类,它可以满足您的期望:

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)

回答by Mark

I know this is super old - but for those looking to split a list into equal partitions (with remainders), and you miss Tim's comment on the original post, the most recent groovy way is the collate() method for List objects that has been available since Groovy 1.8.6.

我知道这太旧了 - 但是对于那些希望将列表分成相等的分区(带有余数)的人,并且您错过了 Tim 对原始帖子的评论,最近的常规方法是 List 对象的 collat​​e() 方法自 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)

回答by devside

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
}

回答by Pierre-David Belanger

This question is old, but I want to share anyway what I came up with to split a list in equal sized lists.

这个问题很老,但无论如何我想分享我想出的将列表拆分为相同大小的列表的方法。

list.collateis great, but did not work for me, as I needed the lists to be split evenly.

list.collate很棒,但对我不起作用,因为我需要将列表平均拆分。

Where is what I do:

我在哪里做什么:

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)
}