在Groovy中总结2个列表的内容

时间:2011-01-03 12:25:43

标签: groovy arraylist sum

我在Groovy中有两个列表,需要对两者的内容求和。

例如:

list1 = [1,1,1]
list2 = [1,1,1]

我期待这个结果:

total = [2,2,2]

我尝试用+运算符o .sum方法求和,但我有一个列表的串联。

[1, 1, 1, 1, 1, 1]

Groovy足够groovy还是我需要遍历列表中的每个元素?

5 个答案:

答案 0 :(得分:33)

Groovy的List.transpose()在某些其他语言中与zip类似。试试这个:

list1 = [1,2,3]
list2 = [4,5,6]
assert [list1, list2].transpose()*.sum() == [5,7,9]

答案 1 :(得分:4)

我不知道内置解决方案,但这是使用collect和Java Queue的{​​{1}}方法的解决方法:

poll()

答案 2 :(得分:2)

在大多数函数式编程语言中,这是通过使用map2(ocaml)或zipWith(haskell)函数来完成的,例如:

let total = List.map2 (+) list1 list2;;

我在groovy文档中找不到任何等效文件,但显然,您可以轻松定义zipWith(在http://cs.calstatela.edu/wiki/index.php/Courses/CS_537/Summer_2008/Chapter_4._Collective_Groovy_datatypes找到):

zipWith = {f, a, b -> 
 result = []
 0.upto(Math.min(a.size(), b.size())-1){index -> result << f(a[index], b[index])}
 result}

assert zipWith({x, y -> x + y}, [1, 2, 3], [4, 5, 6, 7]) ==  [5, 7, 9]

答案 3 :(得分:1)

Prototype(JavaScript框架)有method zip(),可以完全满足您的需求。我知道,这对你没有帮助。有趣的是,我希望Groovy有类似的东西,但我在CollectionList类中找不到任何内容。

无论如何,这是zip()

的一个不太漂亮的实现
List.metaClass.zip = { List other, Closure cl ->
    List result = [];
    Iterator left = delegate.iterator();
    Iterator right = other.iterator();
    while(left.hasNext()&& right.hasNext()){
        result.add(
            cl.call(left.next(), right.next())
        );
    }
    result;
}

这就是行动:

def list1 = [1, 1, 1]
def list2 = [1, 1, 1]

print (list1.zip(list2) {it1, it2 -> it1 + it2})

输出:

  

[2,2,2]


当然,如果你想要解决你的问题(而不是实现通用的zip / map函数),你也可以用不太通用的方式做到这一点:

List.metaClass.addValues = { List other ->
    List result = [];
    Iterator left = delegate.iterator();
    Iterator right = other.iterator();
    while(left.hasNext()&& right.hasNext()){
        result.add(
            left.next() + right.next()
        );
    }
    result;
}

def list1 = [1, 1, 1]
def list2 = [1, 1, 1]

print (list1.addValues(list2))
// Output again: [2, 2, 2]

答案 4 :(得分:0)

如果您发现上面的。* sum()解决方案有点令人困惑(尽管很好),您也可以这样做:

l1=[1,2,3]
l2=[4,5,6]

println([l1,l2].transpose().collect{it[0]+it[1]})

当然,它允许更复杂的计算,而不仅仅是求和。