2012-02-24 33 views
28

Có một số .collect có chỉ mục không? Tôi muốn làm một cái gì đó như thế này:. Thu thập chỉ mục

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

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

(tức là tôi muốn thiết lập position đến một giá trị mà sẽ chỉ ra thứ tự trong danh sách.)

+2

có vẻ như đó là một tính năng được yêu cầu http: //jira.codehaus.org/browse/GROOVY-2838 – dstarh

+0

trả lời với một giải pháp thực tế dưới đây – dstarh

+0

Điều gì không có tình yêu cho thu thập của tôi với chỉ mục :) – dstarh

Trả lời

11

eachWithIndex có lẽ sẽ làm việc tốt hơn:

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

Sử dụng collectX không thực sự cần thiết vì bạn chỉ đang sửa đổi bộ sưu tập và không trả lại các phần cụ thể của bộ sưu tập đó vào bộ sưu tập mới.

+9

trừ khi bạn cần nó để trả lại bộ sưu tập mới – dstarh

+1

@dstarh - Phải, nhưng câu hỏi cho biết "Tôi muốn đặt vị trí thành giá trị", điều này sẽ làm cho bộ sưu tập dường như không cần thiết. –

+4

đã đồng ý, việc thu thập có thể không cần thiết trong trường hợp này. Đã có trong một chuỗi các cuộc gọi khác sẽ khác. Tuy nhiên tôi vẫn muốn xem một tập hợp với chỉ số – dstarh

6

này nên thực hiện chính xác những gì bạn muốn

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

Giống như dstarh nói, trừ khi bạn đang tìm kiếm một phương pháp không phá hủy mà trả về một bản đồ mới với các chỉ số của bạn cư, Rob Hruska 's câu trả lời là những gì bạn 'Đang tìm kiếm.

dstarh câu trả lời của bạn cung cấp cho bạn phiên bản không phá hủy collectWithIndex, nhưng cũng xử lý tập hợp kết quả thực tế.

Tôi thường tìm cách tốt nhất để giao những vật nặng như vậy cho đối tượng tiếp nhận để có thể chơi tốt với việc thực hiện đa hình collect, tức là trong trường hợp một lớp cụ thể thực hiện collect khác nhau (chỉ cần đặt kết quả trong một mảng) collectWithIndex ủy quyền cho nó sẽ đảm bảo hành vi thống nhất. Dưới đây là cách mã sẽ trông:

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

Tham khảo this gist cho một ví dụ cho cả eachWithIndexcollectWithIndex.

Ngoài ra, như các ý kiến ​​để nhà nước câu hỏi của bạn, có hai vấn đề Jira mở cho tính năng chúng tôi đã described- GROOVY-2383 & GROOVY-3797

13

Hơi groovier phiên bản của collectWithIndex:

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

hoặc thậm chí

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

Nếu không thêm bất kỳ phương pháp tiện ích mở rộng nào, bạn có thể thực hiện điều này một cách thẳng thắn orward way:

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

Nó chắc chắn sẽ hữu ích cho phương pháp này để tồn tại tự động.

60

Vì Groovy 2.4.0 có phương thức withIndex() được thêm vào java.lang.Iterable.

Vì vậy, trong một thời trang chức năng (không có tác dụng phụ, không thay đổi), có vẻ như

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

Bỏ phiếu rằng đây phải là câu trả lời hay nhất. – solvingJ

Các vấn đề liên quan