2013-06-02 32 views
9

Trong mã này tôi muốn tăng index để đặt nó vào mỗi kết quả ing yield.Scala for-loop. Lấy chỉ mục theo cách consice

var index=0 

for(str <- splitToStrings(text)) yield { 

    if (index != 0) index += 1    // but index is equal to `0` all the time 

    new Word(str, UNKNOWN_FORM, index) 
} 

Tại sao tôi không thể thay đổi index? Và cách tốt nhất để thực hiện logic này là gì, cố gắng súc tích?

Trả lời

22

Phương pháp zipWithIndex trên hầu hết các bộ sưu tập trình tự giống như sẽ cung cấp cho bạn một chỉ số zero-based, incrementing với mỗi phần tử:

for ((str, index) <- splitToStrings(text).zipWithIndex) 
    yield new Word(str, UNKNOWN_FORM, index) 
+0

Điều đó thật tuyệt. Tôi đã thấy loại chuyển đổi này rồi. Nhưng nó vẫn còn trong kiến ​​thức thụ động. Đó là thực sự súc tích. – ses

+0

sẽ không hiệu quả? –

6

Vì chỉ mục ban đầu được đặt thành 0, do đó, điều kiện của bạn index != 0 không bao giờ được thực thi thành đúng và chỉ mục không bao giờ được tăng lên. Có thể bạn không cần điều kiện này? Có lẽ bạn có thể đếm kết quả sau đó? Bây giờ tôi thấy chỉ mục đó được sử dụng trong vòng lặp. Sau đó, bạn phải sử dụng @BenJames answer hoặc chuyển tiếp.

+0

yep. đó là ngu ngốc fro bên cạnh tôi. ít nhất tôi rất vui vì không có bất ngờ từ năng suất. (Tôi chỉ cần đặt nó vì tôi muốn bắt đầu từ 0-index). Tôi nghĩ rằng một cái gì đó không đúng cách vì scala nhưng không phải tôi :). nhưng trường hợp differennt này%) có rất nhiều điều ngạc nhiên tôi đã có gần đây .. đó là lý do tại sao – ses

1
splitToStrings(text).foldLeft(0,List[Word]){(a,b) => { 
    if(a._1!=0) (a._1+1,new Word(str, UNKNOWN_FORM, index) :: b) 
    else (a._1,new Word(str, UNKNOWN_FORM, index) :: b) 
}} 

Tôi đang sử dụng foldLeft ở đây với một tuple như: bắt đầu từ cơ sở với index = 0 và trống List. Sau đó tôi lặp qua từng phần tử.

Trên a là bộ dữ liệu này. Tôi kiểm tra giá trị index và tăng giá trị đó. Khác tôi không thêm index. Và tôi thêm Word mới vào danh sách.

Cuối cùng, bạn nhận được một bộ chứa giá trị chỉ mục và tổng Danh sách chứa tất cả các từ.

+2

Mã như thế này có thể dễ dàng sử dụng một số từ giải thích để đi với nó. – likeitlikeit

3

zipWithIndex sẽ sao chép và tạo ra một bộ sưu tập mới, vì vậy tốt hơn làm cho nó lười biếng khi bộ sưu tập là có tiềm năng lớn

for ((str, index) <- splitToStrings(text).view.zipWithIndex) 
    yield new Word(str, UNKNOWN_FORM, index) 

Trong thực tế, nếu bạn đang làm việc với một chuỗi được lập chỉ mục, sau đó một cách hiệu quả hơn là để sử dụng indices, tạo ra phạm vi của tất cả các chỉ số của chuỗi này.

val strs = splitToStrings(text) 

for(i <- strs.indices) yield { 
    new Word(strs(i), UNKNOWN_FORM, i) 
} 
+1

điều này sẽ đi mặc dù toàn bộ danh sách tất cả các thời gian để có được mục theo chỉ mục: strs (i). có thể chậm. – ses

+0

câu trả lời được cập nhật. Trình tự cần được lập chỉ mục để cung cấp hiệu suất truy cập ngẫu nhiên tốt. – Max