Ответ 1
Groovy List.transpose()
работает как zip
на некоторых других языках. Попробуйте следующее:
list1 = [1,2,3]
list2 = [4,5,6]
assert [list1, list2].transpose()*.sum() == [5,7,9]
У меня есть два списка в Groovy и вам нужно суммировать содержимое обоих.
Например:
list1 = [1,1,1]
list2 = [1,1,1]
Я ожидал этого результата:
total = [2,2,2]
Я пытаюсь суммировать с помощью метода operator.sum оператора +, но у меня есть конкатенация списков.
[1, 1, 1, 1, 1, 1]
Он Groovy достаточно Groovy или мне нужно зацикливать каждый элемент списков?
Groovy List.transpose()
работает как zip
на некоторых других языках. Попробуйте следующее:
list1 = [1,2,3]
list2 = [4,5,6]
assert [list1, list2].transpose()*.sum() == [5,7,9]
Я не знаю встроенного решения, но обходное решение с использованием метода collect
и Java Queue
poll()
:
def list1 = [1, 2, 3]
def list2 = [4, 5, 6] as Queue
assert [5, 7, 9] == list1.collect { it + list2.poll() }
В большинстве функциональных языков программирования это делается с помощью функции 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]
Прототип (инфраструктура JavaScript) имеет метод zip()
, который делает именно то, что вам нужно. Это мне не поможет, я знаю. Смешно, я бы ожидал, что Groovy будет иметь что-то подобное, но я не смог найти ничего в Collection
или List
.
В любом случае, это не слишком красивая реализация 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]
Если вы находите решение. * sum() выше немного запутанного для чтения (очень приятно), вы также можете сделать это:
l1=[1,2,3]
l2=[4,5,6]
println([l1,l2].transpose().collect{it[0]+it[1]})
Конечно, это позволяет более сложные вычисления, чем просто суммирование.