28

私がこれを持っている場合:

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

これ(または同様のこと)を可能にする組み込みのものはありますか?

array.split(2)

そして取得:

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

4

9 に答える 9

79

編集groovy1.8.6以降、リストで照合方法を使用できます

def origList = [1, 2, 3, 4, 5, 6, 7, 8, 9]
assert [[1, 2, 3, 4], [5, 6, 7, 8], [9]] == origList.collate(4)

injectと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)

編集:空のリストの問題を修正しました

于 2010-05-28T08:32:32.240 に答える
21

これを処理するためにgroovyに組み込まれているものは何もない(少なくとも2つ以上のパーティションの場合)という点でChrisに同意しますが、あなたの質問は彼とは異なる質問であると解釈しました。これがあなたが求めていると私が思うことをする実装です:

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)
于 2010-05-28T03:52:36.383 に答える
17

グルーヴィーな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.

残りを削除するなど、他のオプションを提供する他のパラメーターがいくつかあるため、詳細についてはGroovyリストのドキュメントを参照してください。

于 2012-06-01T00:28:17.047 に答える
9

私は同じ問題を探していましたがcollate()、リストの方法が非常に役立つことがわかりました。

array.collate(2)

ドキュメントへのリンクは次のとおりです

于 2015-02-06T14:31:36.903 に答える
4

それを行うための組み込みはありませんが、書くのは難しくありません。

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
于 2010-05-27T23:24:30.870 に答える
3

これは、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)
于 2010-05-28T08:26:32.797 に答える
2

これは非常に古いことですが、リストを(残りの部分を含む)等しいパーティションに分割しようとしている人にとって、元の投稿に対するTimのコメントを見逃している場合、最新のグルービーな方法は、以前のListオブジェクトのcollat​​e()メソッドです。 Groovy1.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)
于 2013-06-20T19:06:17.197 に答える
1
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
}
于 2012-09-26T15:43:15.770 に答える
0

この質問は古いですが、リストを同じサイズのリストに分割するために私が思いついたものをとにかく共有したいと思います。

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)
}
于 2013-01-11T19:26:17.513 に答える