.collect与索引

zor*_*119 38 iteration collections groovy

.collect指数吗?我想做这样的事情:

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

myList.collect { index ->
    it.position = index
}
Run Code Online (Sandbox Code Playgroud)

(即我想设置position一个值,表示列表中的顺序)

Ber*_*ium 85

从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"]] 
}
Run Code Online (Sandbox Code Playgroud)

  • 投票表明这应该是最好的答案. (7认同)

Mat*_*att 13

稍微更加时髦的collectWithIndex版本:

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

甚至

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


Rob*_*ska 12

eachWithIndex 可能会更好地工作:

myList.eachWithIndex { it, index ->
    it.position = index
}
Run Code Online (Sandbox Code Playgroud)

使用a collectX似乎并不是必需的,因为您只是修改集合而不是将其中的特定部分返回到新集合中.

  • 除非你需要它来返回一个新的集合 (11认同)
  • 同意,在这种情况下可能没有必要收集.如果它在一系列其他呼叫中会有所不同.不过我仍然希望看到带索引的收藏品 (4认同)

dst*_*arh 7

这应该完全符合你的要求

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]]
Run Code Online (Sandbox Code Playgroud)


pic*_*ypg 5

无需添加任何扩展方法,您可以以非常简单的方式执行此操作:

def myList = [1, 2, 3]
def index = 0
def myOtherList = myList.collect {
  index++
}
Run Code Online (Sandbox Code Playgroud)

不过,这种方法自动存在肯定会很有用。