Her biri için Ruby'de otomatik sayaç?


134

Bir for-each ve bir sayaç kullanmak istiyorum:

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

Bunu yapmanın daha iyi bir yolu var mı?

Not:blahs Bir dizi veya karma olup olmadığını bilmiyorum , ancak blahs[i]yapmak zorunda olmak daha seksi yapmaz. Ayrıca i++Ruby'de nasıl yazılacağını bilmek istiyorum .


Teknik olarak, Matt ve Squeegy'nin cevabı önce geldi, ama paradoja'ya en iyi yanıtı veriyorum, bu yüzden SO'daki puanların etrafına yayıldı. Ayrıca cevabı, hala alakalı olan sürümlerle ilgili not aldı (Ubuntu 8.04'üm Ruby 1.8.6 kullanıyorsa).


Kullandım mı puts "#{i} #{blah}"çok daha özlü olduğu.


Ruby'de artış operatörü yok. Orada yazdığınız n + = 1 en yakın eşdeğerdir. Kendisi n = n + 1 için kısaltma olan n + = 1 için sözdizimsel şeker olması gerekir. ++ fikri reddedildi çünkü değişkeni yeniden atadığınız gerçeğini gizliyor. rubyurl.com/Dsb1
Chuck

Güzel! Teşekkürler Chuck. Java'da ++ i ve i ++ öğrenmek zorunda kaldım, bu yüzden her zaman orada olacağını düşündüm.
Dan Rosenstark

Yanıtlar:


190

İnsanların söylediği gibi,

each_with_index

ancak yineleyicinin "her biri" den farklı bir dizin oluşturmasını istiyorsanız (örneğin, bir dizinle veya bunun gibi bir şeyle eşlemek istiyorsanız), numaralandırıcıları each_with_index yöntemiyle birleştirebilir veya basitçe with_index ile kullanabilirsiniz:

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

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

Bu yakut 1.8.7 ve 1.9'dan yapabileceğiniz bir şey.


1
Bunun 1.9'da yeni olduğunu belirtmek gerekir.
Zach Langley

1
İyi gördüm. Aslında, 1.8.7'de de var, ancak eklemeye değer bir şey.
paradoja

Hepsini Ubuntu'ya yüklediysem neden Ruby 1.8.6 kullanıyorum? 1.8.7 deneysel / beta mı?
Dan Rosenstark

Hangi Ubuntu'yu kullanıyorsunuz? Intrepid'de 1.8.7 var. Son kararlı sürüm ( ruby-lang.org/en/downloads ). Ancak, 1.8.6 yakut monkeypatch aynı davranışı sahip olabilir (bkz strictlyuntyped.com/2008/09/ruby-187s-enumerator-class.html ).
paradoja

3
Dağıtımın geride kalmasından bıktım, bu yüzden Ubuntu ve Linux Mint üzerindeki Ruby kurulumumu yönetmek için rvm kullanmaya başladım.
Tin Man

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

Bunu bunun için yapamazsın. Genellikle her bir şahsen daha açıklayıcı çağrıları severim. Kısmen, sözdiziminin sınırına ulaştığınızda diğer formlara geçişi kolay olduğu için.


Güzel, sözdizimi ile ilgili sınırlarla ilgili noktayı görüyorum. Birden fazla parametreli bloklara alışmak zorundayım.
Dan Rosenstark

11

Evet, collection.eachdöngüler yapmak ve ardından each_with_indexdizini almak.

Muhtemelen bir Ruby kitabı okumalısınız, çünkü bu temel Ruby ve eğer bilmiyorsanız, büyük belada olacaksınız (deneyin: http://poignantguide.net/ruby/ ).

Ruby kaynak kodundan alınmıştır:

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

Sorun değil, yardımcı olduğuma sevindim. .Each bloğu hakkında "demek" demek istemedim - bunlar temel yakut yapılardır ve onları anında öğrenmek gerçekten, gerçekten acı verici olacaktır. :) En iyi mermi ısırmak ve okuma birkaç saat geçirmek için!
Matt Rogish

6

Yeni sürümüne sahip each_with_indexdeğilseniz, zipdizinleri öğelerle eşleştirmek için yöntemi kullanabilirsiniz :

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

hangi üretir:

1 one
2 two
3 three
4 four
5 five

1
Bu kodu '%s %s' % [1, "two"]Ruby belgelerindeki cevabınızdan nerede bulabilirim ? Yardımınız ve sıkıştırma ve eşleme için tek bir satır kullanarak dikey alanı koruduğunuz için teşekkür ederiz.
Dan Rosenstark

1
Bu bağlamda,% -sign işleci String sınıfının bir yöntemidir. Bu konuyu ruby-doc.org/core/classes/String.html#M000770 adresinden okuyabilirsiniz . Veya komut istemine ri String #% yazabilirsiniz. Veya tanıyan tüm belgelendirilmiş sınıfları görmek için ri% yazabilirsiniz, örneğin ri Fixnum #% 'da daha tanıdık anlam.
George

4

Yapmakla ilgili sorunuza gelince i++, bunu Ruby'de yapamazsınız. Sahip olduğunuz i += 1ifade tam olarak nasıl yapmanız gerektiğidir.



1

Eğer blahsEnumerable içinde karışımları, bunu yapmak mümkün olmalıdır bir sınıftır:

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

1

Her biri için yakut indeksi almak istiyorsanız, o zaman kullanabilirsiniz

.each_with_index

İşte nasıl .each_with_indexçalıştığını gösteren bir örnek :

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

Bu yazdırılacak:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.