2009-02-10 31 views
125

Tôi muốn sử dụng một for-each và một bộ đếm:Truy cập tự động trong Ruby cho mỗi?

i=0 
for blah in blahs 
    puts i.to_s + " " + blah 
    i+=1 
end 

Có cách nào tốt hơn để làm điều đó?

Lưu ý: Tôi không biết nếu blahs là mảng hoặc băm, nhưng phải làm blahs[i] sẽ không làm cho nó hấp dẫn hơn nhiều. Tôi cũng muốn biết cách viết i++ trong Ruby.


Về mặt kỹ thuật, câu trả lời của Matt và Squeegy đã được đưa ra trước, nhưng tôi đưa ra câu trả lời tốt nhất cho paradoja để lan truyền các điểm trên SO. Ngoài ra câu trả lời của ông có ghi chú về các phiên bản, mà vẫn còn có liên quan (miễn là Ubuntu 8.04 của tôi đang sử dụng Ruby 1.8.6).


Nên sử dụng puts "#{i} #{blah}", gọn gàng hơn rất nhiều.

+0

Không có toán tử tăng trong Ruby. Các n + = 1 bạn đã viết lên có tương đương gần nhất. Nó sẽ phải được cú pháp đường cho n + = 1, mà chính nó là viết tắt của n = n + 1. Ý tưởng của ++ đã bị từ chối vì nó che giấu sự thật rằng bạn đang gán lại biến. http://rubyurl.com/Dsb1 – Chuck

+0

Rất tốt! Cảm ơn Chuck. Tôi đã buộc phải họC++ i và i ++ trong Java, vì vậy tôi chỉ nghĩ rằng nó sẽ luôn luôn ở đó. –

Trả lời

183

Khi mọi người đã nói, bạn có thể sử dụng

each_with_index 

nhưng nếu bạn muốn chỉ số với một trình lặp khác với "mỗi" (ví dụ, nếu bạn muốn ánh xạ với một chỉ mục hoặc một cái gì đó tương tự), bạn có thể nối các toán tử với phương thức each_with_index hoặc chỉ cần sử dụng with_index:

blahs.each_with_index.map { |blah, index| something(blah, index)} 

blahs.map.with_index { |blah, index| something(blah, index) } 

Đây là thứ bạn có thể làm từ ruby ​​1.8.7 và 1.9.

+1

Cần lưu ý rằng đây là điểm mới trong phiên bản 1.9. –

+1

Cũng được phát hiện. Trên thực tế, nó cũng là 1,8,7, nhưng nó là một cái gì đó đáng giá thêm. – paradoja

+0

tại sao tôi trên Ruby 1.8.6 nếu tôi vừa cài đặt toàn bộ thứ trên Ubuntu? 1.8.7 thử nghiệm/beta? –

10

Có, đó là collection.each để làm vòng lặp và sau đó each_with_index để nhận chỉ mục.

Bạn có lẽ nên đọc một cuốn sách Ruby vì đây là Ruby cơ bản và nếu bạn không biết nó, bạn sẽ gặp rắc rối lớn (thử: http://poignantguide.net/ruby/).

Taken từ mã nguồn Ruby:

hash = Hash.new 
%w(cat dog wombat).each_with_index {|item, index| 
    hash[item] = index 
} 
hash #=> {"cat"=>0, "wombat"=>2, "dog"=>1} 
+0

Cảm ơn bạn đã liên kết (xuất sắc) và câu trả lời. –

+0

Không sao, vui lòng giúp đỡ. Không có nghĩa là "có ý nghĩa" về khối .each - đây là những cấu trúc cơ bản của ruby ​​và học chúng trên bay sẽ thực sự, thực sự đau đớn. :) Tốt nhất để cắn đạn và dành một vài giờ đọc! –

+0

Đừng lo lắng, cảm ơn câu trả lời của bạn, @Matt. –

53
[:a, :b, :c].each_with_index do |item, i| 
    puts "index: #{i}, item: #{item}" 
end 

Bạn không thể làm điều này với cho. Tôi thường thích cuộc gọi khai báo nhiều hơn cho từng cá nhân. Một phần vì dễ dàng chuyển đổi sang các biểu mẫu khác khi bạn đạt đến giới hạn cú pháp.

+0

Tốt, tôi thấy điểm về giới hạn với cú pháp. Tôi phải quen với việc chặn nhiều thông số. –

1

Nếu blahs là một lớp pha trộn trong Enumerable, bạn sẽ có thể để làm điều này:

blahs.each_with_index do |blah, i| 
    puts("#{i} #{blah}") 
end 
1

Loạt enumerating enumerable khá đẹp.

+0

Rất tốt, cảm ơn vì điều đó và chúc may mắn trên SO. –

4

Đối với câu hỏi của bạn về việc thực hiện i++, tốt, bạn không thể làm điều đó trong Ruby. Tuyên bố i += 1 bạn có là chính xác cách bạn phải làm điều đó.

+0

Thật tuyệt, cảm ơn, đã được đề cập trong các ý kiến ​​về câu hỏi ... –

6

Nếu bạn không có phiên bản mới của each_with_index, bạn có thể sử dụng phương pháp zip để ghép các chỉ số với các yếu tố:

blahs = %w{one two three four five} 
puts (1..blahs.length).zip(blahs).map{|pair|'%s %s' % pair} 

trong đó sản xuất:

1 one 
2 two 
3 three 
4 four 
5 five 
+1

Tôi có thể tìm mã này từ câu trả lời của bạn ''% s% s'% [1," hai "]' trong tài liệu Ruby? Cảm ơn sự giúp đỡ của bạn và để bảo tồn không gian theo chiều dọc bằng cách sử dụng một dòng để nén và ánh xạ. –

+1

Trong ngữ cảnh này, toán tử% -sign là một phương thức của lớp String. Bạn có thể đọc về nó tại http://ruby-doc.org/core/classes/String.html#M000770. Hoặc bạn có thể gõ ri String #% tại dấu nhắc lệnh. Hoặc bạn có thể nhập ri% để xem tất cả các lớp được tài liệu nhận ra nó, ví dụ: ý nghĩa quen thuộc hơn ở ri Fixnum #%. – George

1

Nếu bạn muốn nhận được chỉ số của ruby ​​cho mỗi, sau đó bạn có thể sử dụng

.each_with_index 

Đây là một n ví dụ cho thấy cách .each_with_index công trình:

range = ('a'..'z').to_a 
length = range.length - 1 
range.each_with_index do |letter, index| 
    print letter + " " 
    if index == length 
     puts "You are at last item" 
    end 
end 

này sẽ in:

a b c d e f g h i j k l m n o p q r s t u v w x y z You are at last item 
Các vấn đề liên quan