7

有没有办法在以下示例中删除变量“i”并且仍然可以访问正在打印的项目的索引?

def i = 0;
"one two three".split().each  {
    println ("item [ ${i++} ] = ${it}");
}

=============== 编辑 ================

我发现一种可能的解决方案是使用“eachWithIndex”方法:

"one two three".split().eachWithIndex  {it, i
    println ("item [ ${i} ] = ${it}");
}

请让我知道是否有其他解决方案。

4

3 回答 3

12

您可以使用eachWithIndex()

"one two three four".split().eachWithIndex() { entry, index ->
      println "${index} : ${entry}" }

这将导致

0 : one
1 : two
2 : three
3 : four
于 2012-04-30T08:16:00.673 回答
0

不确定您正在寻找什么“其他解决方案”......我能想到的唯一其他可以做的事情(使用 Groovy 1.8.6)是这样的:

"one two three".split().with { words ->
  [words,0..<words.size()].transpose().collect { word, index ->
    word * index
  }
}

如您所见,这也允许您使用collect索引(因为没有collectWithIndex方法)。

于 2012-04-30T08:31:05.973 回答
0

另一种方法,如果你想在其他方法上使用集合的索引,而不是each定义一个enumerate返回 pairs 的方法[index, element],类似于Python 的 enumerate

Iterable.metaClass.enumerate = { start = 0 -> 
    def index = start
    delegate.collect { [index++, it] }
}

因此,例如:

assert 'un dos tres'.tokenize().enumerate() == [[0,'un'], [1,'dos'], [2,'tres']]

(请注意,我使用tokenize而不是split因为前者返回 Iterable,而后者返回 a String[]

我们可以使用这个新的集合each,如你所愿:

'one two three'.tokenize().enumerate().each { index, word ->
    println "$index: $word"
}

或者我们可以将它与其他迭代方法一起使用:D

def repetitions = 'one two three'.tokenize().enumerate(1).collect { n, word -> 
    ([word] * n).join(' ')
}
assert repetitions == ['one', 'two two', 'three three three']

注意:定义该方法的另一种enumerate方法,遵循 tim_yates 的更多功能方法是:

Iterable.metaClass.enumerate = { start = 0 -> 
    def end = start + delegate.size() - 1
    [start..end, delegate].transpose()
}
于 2012-04-30T19:02:26.517 回答