.collect with an index

22,506

Solution 1

Since Groovy 2.4.0 there is a withIndex() method which gets added to java.lang.Iterable.

So, in a functional fashion (no side effect, immutable), it looks like

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"]] 
}

Solution 2

eachWithIndex would probably work better:

myList.eachWithIndex { it, index ->
    it.position = index
}

Using a collectX doesn't really seem necessary since you're just modifying the collection and not returning particular pieces of it into a new collection.

Solution 3

Slightly groovier version of collectWithIndex:

List.metaClass.collectWithIndex = {body->
    def i=0
    delegate.collect { body(it, i++) }
}

or even

List.metaClass.collectWithIndex = {body->
    [delegate, 0..<delegate.size()].transpose().collect(body)
}

Solution 4

This should do exactly what you want

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]]

Solution 5

Without adding any extension methods, you can do this in a pretty straightforward way:

def myList = [1, 2, 3]
def index = 0
def myOtherList = myList.collect {
  index++
}

It would certainly be useful for this method to exist automatically though.

Share:
22,506
zoran119
Author by

zoran119

Updated on July 09, 2022

Comments

  • zoran119
    zoran119 almost 2 years

    Is there a .collect with an index? I want to do something like this:

    def myList = [
        [position: 0, name: 'Bob'],
        [position: 0, name: 'John'],
        [position: 0, name: 'Alex'],
    ]
    
    myList.collect { index ->
        it.position = index
    }
    

    (ie. I want to set position to a value which will indicate the order in the list)