.collect с индексом
Есть ли .collect
с индексом? Я хочу сделать что-то вроде этого:
def myList = [
[position: 0, name: 'Bob'],
[position: 0, name: 'John'],
[position: 0, name: 'Alex'],
]
myList.collect { index ->
it.position = index
}
(т.е. я хочу установить position
значение, которое укажет порядок в списке)
Ответы
Ответ 1
eachWithIndex
, вероятно, будет работать лучше:
myList.eachWithIndex { it, index ->
it.position = index
}
Использование collectX
действительно не представляется необходимым, поскольку вы просто модифицируете коллекцию и не возвращаете ее в новую коллекцию.
Ответ 2
Так как Groovy 2.4.0 существует withIndex()
метод, который добавляется к java.lang.Iterable
.
Итак, функционально (без побочного эффекта, неизменяемого), он выглядит как
def myList = [
[position: 0, name: 'Bob'],
[position: 0, name: 'John'],
[position: 0, name: 'Alex'],
]
def result = myList.withIndex().collect { element, index ->
[position: index, name: element["name"]]
}
Ответ 3
Немного важная версия collectWithIndex:
List.metaClass.collectWithIndex = {body->
def i=0
delegate.collect { body(it, i++) }
}
или даже
List.metaClass.collectWithIndex = {body->
[delegate, 0..<delegate.size()].transpose().collect(body)
}
Ответ 4
Это должно делать именно то, что вы хотите
List.metaClass.collectWithIndex = {cls ->
def i = 0;
def arr = [];
delegate.each{ obj ->
arr << cls(obj,i++)
}
return arr
}
def myCol = [
[position: 0, name: 'Bob'],
[position: 0, name: 'John'],
[position: 0, name: 'Alex'],
]
def myCol2 = myCol.collectWithIndex{x,t ->
x.position = t
return x
}
println myCol2
=> [[position:0, name:Bob], [position:1, name:John], [position:2, name:Alex]]
Ответ 5
Без добавления каких-либо методов расширения вы можете сделать это довольно просто:
def myList = [1, 2, 3]
def index = 0
def myOtherList = myList.collect {
index++
}
Конечно, было бы полезно, чтобы этот метод существовал автоматически, хотя.
Ответ 6
Как dstarh, если вы не ищете неразрушающий метод, который возвращает новую карту с заполненными вами индексами, Rob Hruska ответ - это то, что вы ищете.
dstarh дает вам неразрушающую версию collectWithIndex
, но также обрабатывает фактический набор результатов.
Мне обычно лучше всего делегировать такой тяжелый подъем принимающему объекту, чтобы играть хорошо с полиморфными реализациями collect
, т.е. в случае, если конкретный класс реализует collect
по-разному (чем просто помещать результаты в массив), имеющий collectWithIndex
делегировать ему, обеспечит единообразное поведение. Вот как выглядит код:
@Category(List)
class Enumerator {
def enumerateCollecting(Closure closure) {
def index = 0
this.collect { closure.call(it, index++) }
}
}
use(Enumerator) {
['foo', 'bar', 'boo', 'baz'].collectWithIndex { e, i ->
[index: i, element: e]
}
}
Обратитесь к этой теме для примера как для eachWithIndex
, так и collectWithIndex
.
Кроме того, как и комментарии к вашему вопросу, есть две проблемы Jira, открытые для описанной функции - GROOVY -2383 и GROOVY-3797