2010-05-27 27 views
16

Si tengo esto:¿Cómo dividir una lista en listas de igual tamaño en Groovy?

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

¿Hay alguna incorporada que permite que haga esto (o algo similar):

array.split(2) 

y obtener:

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

?

+5

A partir de 1.8.6 maravilloso puede utilizar el [método cotejar] (http://jira.codehaus.org/browse/GROOVY-5283) en las listas de –

Respuesta

15

Estoy de acuerdo con Chris que no hay nada integrado en maravilloso para manejar esto (al menos durante más de 2 particiones), pero interpreté que tu pregunta era preguntar algo diferente de lo que hizo. He aquí una aplicación que hace lo que yo creo que está pidiendo:

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) 
+0

Sí. Esto es lo que estaba buscando. Terminé escribiendo la mía anoche. ¡Gracias! – Geo

+0

@Ted Posible problema de concurrencia con esta función en algunos escenarios, pero de fácil acceso, http://stackoverflow.com/questions/9536552/groovy-collating-list-causes-concurrentmodification-exception – raffian

2

No hay nada orden interna para hacer eso, pero no es difícil escribir:

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 
+1

lado derecho se puede definir como derecha = array [mediados .. -1] (¡La manera maravillosa!) – sbglasius

2

aquí es una versión alternativa, que utiliza características dinámicas de Groovy para agregar un método de división de la clase List, que hace lo que esperas:

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

EDITAR a partir de 1.8.6 maravilloso se puede utilizar el método de collate en las listas

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

Otro método usando inyectar y metaclases

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) 

Editar: fija un problema con la lista vacía

9

Salida maravilloso 1.8.6. Hay un nuevo método de clasificación en la Lista.

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. 

Tome un vistazo a la Groovy List documentation para obtener más información porque hay un par de otros parametros que le dan algunas otras opciones, incluyendo dejar caer el resto.

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

Esta pregunta es antigua, pero quiero compartir de todos modos lo que se me ocurrió para dividir una lista en listas de igual tamaño.

list.collate es genial, pero no funcionó para mí, ya que necesitaba las listas para dividir de manera uniforme.

Donde es lo que hago:

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

Sé que esto es muy antigua - pero para aquellos que buscan dividir una lista en la igualdad de las particiones (con restos), y omite el comentario de Tim en el post original, la forma groovy más reciente es el método de intercalación() para objetos List que ha estado disponible desde 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) 
3

que estaba buscando el mismo problema y me encontré con el método collate() para las listas a ser muy útil.

array.collate(2) 

Here es el enlace a la documentación.

Cuestiones relacionadas