2010-10-22 28 views
72

Nếu tôi có một vòng lặp nhưCho cuối của một vòng lặp .each trong ruby ​​

users.each do |u| 
    #some code 
end 

đâu người dùng là một hash của nhiều người dùng. Có gì logic có điều kiện dễ dàng nhất để xem nếu bạn đang ở trên người sử dụng cuối cùng trong băm người sử dụng và chỉ muốn thực thi mã cụ thể cho người dùng cuối cùng nên cái gì như

users.each do |u| 
    #code for everyone 
    #conditional code for last user 
    #code for the last user 
    end 
end 

Cảm ơn

+0

Bạn có thực sự có nghĩa là băm không? Đặt hàng trên một băm không phải luôn luôn đáng tin cậy (tùy thuộc vào cách bạn thêm những thứ vào băm và phiên bản ruby ​​bạn đang sử dụng). Với thứ tự không đáng tin cậy, mục 'cuối cùng' sẽ không nhất quán. Mã trong câu hỏi và câu trả lời bạn nhận được phù hợp hơn với một mảng hoặc có thể đếm được. Ví dụ, băm không có phương thức 'each_with_index' hoặc' last'. – Shadwell

+1

'Hash' trộn trong Enumerable, do đó, nó có' each_with_index'. Ngay cả khi các khóa băm không được sắp xếp, loại logic này luôn xuất hiện khi hiển thị chế độ xem, trong đó mục cuối cùng có thể được hiển thị khác nhau bất kể nó có thực sự là "cuối cùng" hay không. – Raphomet

+0

Tất nhiên, khá đúng, hashes có 'each_with_index', xin lỗi. Vâng, tôi có thể thấy rằng nó sẽ xuất hiện; chỉ cố làm sáng tỏ câu hỏi. Cá nhân câu trả lời tốt nhất cho tôi là sử dụng '.last' nhưng điều đó không áp dụng cho một băm chỉ là một mảng. – Shadwell

Trả lời

119
users.each_with_index do |u, index| 
    # some code 
    if index == users.size - 1 
    # code for the last user 
    end 
end 
+1

Vấn đề với điều này là một điều kiện được chạy qua mỗi lần. sử dụng '.last' bên ngoài vòng lặp. – bcackerman

+1

Tôi chỉ muốn thêm rằng nếu bạn đang lặp qua một băm, bạn phải viết nó như: 'users.each_with_index do | (key, value), index | # code của bạn end' – HUB

+0

Tôi biết nó không hoàn toàn giống như câu hỏi, nhưng mã này hoạt động tốt hơn Tôi nghĩ nếu bạn muốn làm điều gì đó cho mọi người NHƯNG người dùng cuối cùng, vì vậy tôi sẽ upvoting vì đó là những gì tôi đang tìm kiếm – WhiteTiger

8

Bạn có cố gắng each_with_index?

users.each_with_index do |u, i| 
    if users.size-1 == i 
    #code for last items 
    end 
end 
5
h = { :a => :aa, :b => :bb } 
h.each_with_index do |(k,v), i| 
    puts ' Put last element logic here' if i == h.size - 1 
end 
36

Nếu nó là một trong hai/hoặc tình huống, nơi bạn đang áp dụng một số mã cho tất cả nhưng người sử dụng cuối cùng và sau đó một số mã độc đáo để chỉ người sử dụng cuối cùng, một trong những khác các giải pháp có thể phù hợp hơn. Tuy nhiên, dường như bạn đang chạy cùng một mã cho tất cả người dùng và một số mã bổ sung cho người dùng cuối cùng. Nếu đó là trường hợp, điều này dường như chính xác hơn, và rõ ràng hơn khẳng định ý định của bạn:

users.each do |u| 
    #code for everyone 
end 

users.last.do_stuff() # code for last user 
+2

+1 vì không cần điều kiện, nếu thích hợp. (Tất nhiên, tôi đã làm ở đây) – Jeremy

+0

@meagar sẽ không lặp lại những người sử dụng này hai lần? – ant

+0

@ant Không, có một vòng lặp và một cuộc gọi đến '.last' không liên quan gì đến vòng lặp. – meagar

17

Tôi nghĩ rằng một cách tiếp cận tốt nhất là:

users.each do |u| 
    #code for everyone 
    if u.equal?(users.last) 
    #code for the last user 
    end 
end 
+17

Vấn đề với câu trả lời này là nếu người dùng cuối cùng cũng xảy ra sớm hơn trong danh sách, sau đó mã điều kiện sẽ được gọi nhiều lần. – evanrmurphy

+0

bạn phải sử dụng 'u.equal? ​​(Users.last)', phương thức 'equal?' So sánh object_id, không phải giá trị của đối tượng. Nhưng điều này sẽ không làm việc với symboles và số. –

0

Không có phương pháp cuối cùng cho băm cho một số phiên bản của ruby

h = { :a => :aa, :b => :bb } 
last_key = h.keys.last 
h.each do |k,v| 
    puts "Put last key #{k} and last value #{v}" if last_key == k 
end 
+0

Đây có phải là câu trả lời giúp cải thiện câu trả lời của người khác không? Vui lòng đăng câu trả lời nào đề cập đến phương pháp 'cuối cùng' và bạn đề xuất gì để khắc phục vấn đề này. – Artemix

+0

Đối với các phiên bản Ruby không có 'last', bộ khóa sẽ không có thứ tự, vì vậy câu trả lời này sẽ trả về kết quả sai/ngẫu nhiên. – meagar

0

Một giải pháp khác là để giải cứu từ StopIteration:

user_list = users.each 

begin 
    while true do 
    user = user_list.next 
    user.do_something 
    end 
rescue StopIteration 
    user.do_something 
end 
+4

Đây không phải là giải pháp tốt cho vấn đề này. Ngoại lệ không nên bị lạm dụng để kiểm soát luồng đơn giản, chúng dành cho các tình huống * ngoại lệ. – meagar

+0

@meagar Điều này thực sự gần như khá mát mẻ. Tôi đồng ý rằng ** ngoại lệ ** không được bảo vệ hoặc những trường hợp ngoại lệ cần được chuyển sang phương pháp cao hơn chỉ nên dành cho các tình huống đặc biệt. Điều này, tuy nhiên, là một cách gọn gàng (và rõ ràng chỉ) của việc tiếp cận với kiến ​​thức bản địa của ruby ​​về nơi mà một iterator kết thúc. Nếu có một cách khác mà, tất nhiên, được ưa thích. Vấn đề duy nhất thực sự tôi muốn thực hiện với điều này là nó dường như bỏ qua và không làm gì cho mục đầu tiên. Sửa chữa nó sẽ đưa nó qua ranh giới của clunkiness. – Adamantish

3

Thỉnh thoảng tôi thấy tốt hơn là tách logic thành hai phần, một cho tất cả người dùng và một cho người cuối cùng. Vì vậy, tôi sẽ làm một cái gì đó như thế này:

users[0...-1].each do |user| 
    method_for_all_users user 
end 

method_for_all_users users.last 
method_for_last_user users.last 
3

Bạn có thể sử dụng @ cách tiếp cận ít ỏi cũng cho một hoặc/hoặc tình huống, nơi bạn đang áp dụng một số mã cho tất cả nhưng người sử dụng cuối cùng và sau đó một số mã độc đáo để chỉ người dùng cuối cùng.

users[0..-2].each do |u| 
    #code for everyone except the last one, if the array size is 1 it gets never executed 
end 

users.last.do_stuff() # code for last user 

Bằng cách này bạn không cần điều kiện!

+0

@BeniBela Không, [-1] là phần tử cuối cùng. Không có [-0]. Vì vậy, thứ hai cuối cùng là [-2]. – coderuby

+0

'người dùng [0 ..- 2]' là chính xác, cũng như 'người dùng [0 ...- 1]'. Lưu ý các toán tử phạm vi khác nhau '..' so với' ... ', xem http://stackoverflow.com/a/9690992/67834 –

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