Подтвердить что ты не робот

.collect с индексом

Есть ли .collect с индексом? Я хочу сделать что-то вроде этого:

def myList = [
    [position: 0, name: 'Bob'],
    [position: 0, name: 'John'],
    [position: 0, name: 'Alex'],
]

myList.collect { index ->
    it.position = index
}

(т.е. я хочу установить position значение, которое укажет порядок в списке)

4b9b3361

Ответ 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