Algorithm 根据groovy中的模式在groovy中混合两个列表?

Algorithm 根据groovy中的模式在groovy中混合两个列表?,algorithm,collections,groovy,Algorithm,Collections,Groovy,我有两个清单,比如: def list1 = [a,b,c,d,e...] def list2 = [1,2,3,4,5... ] 我希望他们以某种模式混合,以便最终列表如下所示: [a,b,c,d,1,2,e,f,g,h,3,4,i,j,k,l,5,6…] 基本上,在列表1中的每个n元素之后,我从列表2中获得m元素 编辑:如果一个列表中的元素用完了,那么剩余列表中的项目只需添加到最终列表中即可 EDIT2:两个列表都可以将对象作为元素 我想找到最有效的方法来解决这个问题。在Groovy中有一

我有两个清单,比如:

def list1 = [a,b,c,d,e...]
def list2 = [1,2,3,4,5... ]
我希望他们以某种模式混合,以便最终列表如下所示:
[a,b,c,d,1,2,e,f,g,h,3,4,i,j,k,l,5,6…]

基本上,在列表1中的每个
n
元素之后,我从列表2中获得
m
元素

编辑:如果一个列表中的元素用完了,那么剩余列表中的项目只需添加到最终列表中即可

EDIT2:两个列表都可以将对象作为元素


我想找到最有效的方法来解决这个问题。

在Groovy中有一种方法:

因此,我有一个方法
mix
,它获取带有整数键(所需元素数)的映射,并将其列为值:

List mix( Map<Integer,List> amounts ) {
  amounts.collect { k, v ->
    v.collate( k )
  }.transpose().flatten()
}
这将返回:

[ 'a', 'b', 'c', 'd', 1, 2,
  'e', 'f', 'g', 'h', 3, 4,
  'i', 'j', 'k', 'l', 5, 6,
  'm', 'n', 'o', 'p', 7, 8,
  'q', 'r', 's', 't', 9, 10 ]
(这里的格式看起来更好)

如您所见,它首先用完了数字,当它用完时,列表结束。这是因为当一个列表的元素用完时,转置停止

编辑: 找到了迭代器的另一种方法(因此它是惰性的,不会消耗比其他情况下所需更多的内存):

然后ret将等于:

['a', 'b', 'c', 'd', 1, 2,
 'e', 'f', 'g', 'h', 3, 4,
 'i', 'j', 'k', 'l', 5, 6,
 'm', 'n', 'o', 'p', 7, 8,
 'q', 'r', 's', 't', 9, 10,
 'u', 'v', 'w', 'x', 'y', 'z']

我有一个基于主要答案的保留剩余元素的函数解决方案

List mix( Map<Integer,List> amounts ) {
    def maxItems = amounts.collect { k, v -> v.size() }.max()
    amounts.collect { k, v ->
        def padding = maxItems - v.size()
        it.addAll((1..padding).collect { null })
        v.collate( k )
    }.transpose().flatten().grep { it }
}
列表组合(映射数量){
def maxItems=amounts.collect{k,v->v.size()}.max()
amounts.collect{k,v->
def padding=maxItems-v.size()
it.addAll((1..padding.collect{null})
v、 核对(k)
}.transpose().flatte().grep{it}
}

我在一个简化版本中测试了它,将三个列表混合在一起,每次只取一个项目。这个想法就是用空对象添加填充,使所有对象都具有相同的长度。

当列表中的元素用完时,您会怎么做?我不使用groovy。如果我用Python告诉你方法会有帮助吗?@tim_yates:我只是从剩下的列表中添加项目together@skyler我从未使用过python:(@AtharvaJohri,所以下面的答案是不好的?我也需要剩余的元素。而且,我的两个初始列表都很庞大!执行
collect()会吗
高效吗?@AtharvaJohri无论如何,你将从这两种方法中列出一个巨大的列表,不是吗?我将尝试一个迭代器版本,但我希望最终你将从该迭代器收集所有值?因此,这里说:没有方法签名:java.util.ArrayList.collectMany()适用于参数类型:(com.ds.core.CategoryController$\u MixingIterator\u closure1)值:[com.ds.core.CategoryController$\u MixingIterator_closure1@4062d86f]可能的解决方案:collectAll(groovy.lang.Closure)、collect(groovy.lang.Closure)、collect(groovy.lang.Closure)我的两个初始列表都有对象。很抱歉没有具体说明!@AtharvaJohri您使用的Groovy版本是什么?@AtharvaJohri如果它小于1.8.1,那么将迭代器构造函数中的
collectMany
行更改为:
amts=amounts.collect{[i++]*it}.flant()
def list1 = 'a'..'z'
def list2 = 1..10

def ret = new MixingIterator( [ list1, list2 ], [ 4, 2 ] ).collect()
// OR FOR GROOVY 1.7.8
// def ret = new MixingIterator( [ list1, list2 ], [ 4, 2 ] ).collect { it }
['a', 'b', 'c', 'd', 1, 2,
 'e', 'f', 'g', 'h', 3, 4,
 'i', 'j', 'k', 'l', 5, 6,
 'm', 'n', 'o', 'p', 7, 8,
 'q', 'r', 's', 't', 9, 10,
 'u', 'v', 'w', 'x', 'y', 'z']
List mix( Map<Integer,List> amounts ) {
    def maxItems = amounts.collect { k, v -> v.size() }.max()
    amounts.collect { k, v ->
        def padding = maxItems - v.size()
        it.addAll((1..padding).collect { null })
        v.collate( k )
    }.transpose().flatten().grep { it }
}