.collect与索引

时间:2012-02-24 13:42:39

标签: collections groovy iteration

是否有.collect的索引?我想做这样的事情:

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

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

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

6 个答案:

答案 0 :(得分:81)

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

答案 1 :(得分:13)

稍微更加时髦的collectWithIndex版本:

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

甚至

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

答案 2 :(得分:12)

eachWithIndex可能效果更好:

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

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

答案 3 :(得分: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]]

答案 4 :(得分:4)

如果不添加任何扩展方法,您可以通过非常简单的方式执行此操作:

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

虽然这种方法自动存在肯定会有用。

答案 5 :(得分:1)

就像dstarh所说的那样,除非你正在寻找一个非破坏性的方法来返回填充了你的索引的新地图,Rob Hruska的答案就是你要找的。

dstarh的答案为您提供了collectWithIndex的非破坏性版本,但也处理了实际的结果集合。

我通常认为最好将这样繁重的工作委托给接收对象,以便与多态collect实现一起使用,即,如果特定类以不同方式实现collect(而不仅仅是得到一个数组),collectWithIndex委托给它将确保统一的行为。以下是代码的外观:

@Category(List)
class Enumerator {
    def collectWithIndex(Closure closure) {
        def index = 0
        this.collect { closure.call(it, index++) }
    }
}

use(Enumerator) {
    ['foo', 'bar', 'boo', 'baz'].collectWithIndex { e, i ->
        [index: i, element: e]
    }
}

有关eachWithIndexcollectWithIndex的示例,请参阅this gist

此外,与您的问题状态的评论一样,我们所描述的功能有两个Jira问题 - GROOVY-2383&amp; GROOVY-3797