2011-01-03 39 views
12

Tôi có hai danh sách trong Groovy và cần tổng hợp nội dung của cả hai.Tổng hợp nội dung của 2 danh sách trong Groovy

Ví dụ:

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

tôi mong đợi kết quả này:

total = [2,2,2] 

tôi cố gắng tổng hợp với phương pháp + .sum điều hành o, nhưng tôi có một nối của các danh sách.

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

Đó là Groovy đủ groovy hoặc tôi cần phải lặp lại từng phần tử trong danh sách?

+1

Có thể lặp lại câu hỏi này: http://stackoverflow.com/questions/4443557/overloading-operator-for-arrays-in-groovy – Northover

Trả lời

33

Groovy của List.transpose() công trình như zip trong một số ngôn ngữ khác. Hãy thử điều này:

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

đó là câu trả lời hay nhất cho đến nay (xin lỗi không upvotes còn lại cho ngày hôm nay). Ngôi sao là gì? –

+2

Đó là [toán tử truyền] (http://docs.codehaus.org/display/GROOVY/Operators?showChildren=false#Operators-SpreadOperator%28.%29), viết tắt để 'thu thập 'trong danh sách. – ataylor

+0

Với câu trả lời tuyệt vời này, tôi nhớ một câu hỏi tôi đã hỏi trước đó: [Clarity vs Obfuscation] (http://stackoverflow.com/questions/4433137/clarity-vs-obfuscation-writing-code) –

2

Trong các ngôn ngữ lập trình chức năng nhất, điều này được thực hiện bằng cách sử dụng một (ocaml) hoặc zipWith chức năng map2 (Haskell), với ví dụ:

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

tôi không tìm thấy bất kỳ tương đương trong tài liệu hấp dẫn, nhưng rõ ràng, bạn có thể dễ dàng xác định zipWith (tìm thấy tại 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] 
1

Prototype (framework JavaScript) có method zip() thực hiện chính xác những gì bạn cần. Điều đó không giúp bạn mặc dù, tôi biết. Hài hước, tôi đã mong đợi Groovy sẽ có một cái gì đó tương tự, nhưng tôi không thể tìm thấy bất cứ điều gì trong lớp Collection hoặc List.

Dù sao, đây là một thực hiện không-quá-xinh đẹp của 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; 
} 

Và ở đây nó là trong hành động:

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

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

Output:

[2, 2, 2]


Tất nhiên bạn cũng có thể làm điều đó theo một cách ít chung nếu bạn muốn giải quyết chính xác vấn đề của bạn (và không thực hiện một zip/chức năng bản đồ generic):

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

Tôi không biết một giải pháp tích hợp, nhưng đây là một cách giải quyết bằng collectpoll() phương pháp Java Queue 's:

def list1 = [1, 2, 3] 
def list2 = [4, 5, 6] as Queue 

assert [5, 7, 9] == list1.collect { it + list2.poll() } 
+1

Đó là bản gốc (+1) –

0

Nếu bạn tìm thấy.* sum() giải pháp trên một chút khó hiểu để đọc (rất tốt đẹp mặc dù) bạn cũng có thể làm điều này:

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

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

Tất nhiên nó cho phép tính toán phức tạp hơn chỉ tổng hợp.

Các vấn đề liên quan