2012-02-24 70 views
28

是否有.collect帶索引?我想要做這樣的事情:。收集索引

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

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

(即我想設置position的值,這將表明在列表中的順序。)

+2

它看起來就像是一個要求的功能HTTP://jira.codehaus。org/browse/GROOVY-2838 – dstarh 2012-02-24 13:46:44

+0

回答下面的實際解決方案 – dstarh 2012-02-24 14:50:35

+0

什麼不愛我的收集指數:) – dstarh 2012-02-27 19:42:22

回答

11

eachWithIndex可能會更好地工作:

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

使用collectX似乎並不是必須的,因爲您只是修改了集合,並沒有將它的特定部分返回到新的集合中。

+9

除非你需要它返回一個新的集合 – dstarh 2012-02-24 13:47:31

+1

@dstarh - 對,但問題是「我想設置一個值的位置」,這將使收集看起來沒有必要。 – 2012-02-24 13:48:19

+4

同意,在這種情況下收集可能是沒有必要的。如果它在一系列其他呼叫中會有所不同。我仍然希望看到索引 – dstarh 2012-02-24 13:50:57

6

這應該做的正是你想要的

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

dstarh說,除非你正在尋找一個返回與索引的新地圖填充的非破壞性的方法,Rob Hruska的答案是什麼,你正在尋找。

dstarh的答案爲您提供了collectWithIndex的非破壞性版本,但也處理實際的結果收集。

我通常發現最好委派這樣繁重到接收對象,以便播放用多態性collect實施方式中,即很好,如果一個特定的類實現collect不同(除了只是把結果以陣列),具有代表它將確保統一的行爲。下面的代碼是什麼樣子:

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

參考this gist爲兩個eachWithIndexcollectWithIndex一個例子。

此外,像評論你的問題的狀態,有兩個問題吉拉開放的功能,我們已經described- GROOVY-2383 & GROOVY-3797

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) 
} 
3

不添加任何擴展方法,你可以做到這一點很簡單向前的方式:

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

這對於這種方法自動存在肯定是有用的。

60

由於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"]] 
} 
+4

的收集投票,​​這應該是最好的答案。 – solvingJ 2016-08-28 00:50:18