Bir Diziyi Ruby'de bir Aralıkla doldurmanın doğru yolu


202

Ben "to_a" yöntemlerini kullanarak aralıkları eşdeğer dizilere dönüştürülüyor örnekleri veren bir kitap üzerinde çalışıyorum

İrb kodu çalıştırmak zaman aşağıdaki uyarıyı alıyorum

 warning: default `to_a' will be obsolete

To_a kullanmanın doğru alternatifi nedir?

dizi ile bir aralığı doldurmanın alternatif yolları var mı?


7
Bir aralığı bir diziye dönüştürmenin en büyük uyarısı, dizi oluşturulduğunda çok fazla bellek tüketebilen büyük bir aralıktır, bu yüzden dikkatli kullanın. Diziyi oluşturmak yerine, bellek tüketimini düşük tutmak için dizi gibi yineleme yapmak daha iyi olabilir. "Gerektiği gibi uygula" işlerinden biri.
Tin Man

Yanıtlar:


358

Uyarıyı kullanarak aralık içeren bir dizi oluşturabilirsiniz,

>> a=*(1..10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Kernel Arrayyöntemi kullanarak ,

Array (1..10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

veya to_a kullanarak

(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

1
Dizi zaten oluşturulmuşsa ve diziye bir aralık eklemek isterseniz: Var order = 1. Sonra order << (2.25).to_a. Ama bu dizi içinde başka bir dizi oluşturur, ben sadece 2 ila 25 aralığı istiyorum. Yine de ben order << (2.25)hata alırsanız Range tamsayı dönüştürmek edemez.
kakubei

1
concatyerine @kakubei kullanın <<. Ayrıca, orderbir tam sayı olmadıkça "Aralığı tamsayıya dönüştüremezsiniz" ifadesini almamalısınız - bu durumda dizi ekleme yerine bit kaydırma yaparsınız.
Kelvin

3
Splat seçeneği Ruby 1.8.7 için çalışmıyor, (1..10).to_ageriye dönük uyumluluk için kullanmanızı tavsiye ederim
kylewelsby

5
Splat kullanımınız kötü. Daha iyi görünümlü seçenek [*1..10].
Hauleth

2
en hızlı yol nedir ??
Andrey Yasinishyn

79

Bu irb benim için çalışıyor:

irb> (1..4).to_a
=> [1, 2, 3, 4]

Fark ettim:

irb> 1..4.to_a
(irb):1: warning: default `to_a' will be obsolete
ArgumentError: bad value for range
        from (irb):1

Belki de parantezleri kaçırıyorsunuz?

(Ruby 1.8.6 patchlevel 114 kullanıyorum)


7
Açıklama : parantez olmadan, 1._ aralığında değil, Fixnum Sınıfının bir örneğinden (bu örnekte 4) to_a yöntemini çağırırsınız. Eğer Fixnum.methods.include?(to_a)yakut 1.9.2'de çalışırsanız, to_a yönteminin artık tanımlanmadığını fark edeceksiniz, bu yüzden neden bu amortisman mesajını 08
Pierre

@Pierre Sanırım demek istedinFixnum.instance_methods.include?(:to_a)
Kelvin

@Kelvin - Aslında methods.include?daha bilgilendirici: $ irb irb(main):001:0> Fixnum.methods.include?(to_a) (irb):1: warning: default to_a 'modası geçecek=> false irb(main):002:0> Fixnum.instance_methods.include?(:to_a) => false
Richard Turner

1
@RichardTurner Ruby 1.8 kullandığınızı varsayıyorum. Korkarım to_ailk formda uyarıyı neyin tetiklediğini yanlış anlıyorsunuz . Aradığınız çünkü bu to_aüzerinde self- aslında olmadığını kontrol edilmez to_aFixnum bir yöntemdir. to_aKendi başınıza aramayı deneyin , aynı uyarıyı göreceksiniz.
Kelvin

@Kelvin - Duh! Kuruş düşer. Teşekkürler.
Richard Turner

34

Bunu yaptığınız anlaşılıyor:

0..10.to_a

Uyarı Aralık # ila_a arasında değil Fixnum # ila_a arasındadır. Bunun yerine şunu deneyin:

(0..10).to_a



4

Sadece daha büyük miktardan daha küçük miktarlara kadar aralıkları kullanmaya çalıştım ve beklemediğim sonucu aldım:

irb(main):007:0> Array(1..5)
=> [1, 2, 3, 4, 5]
irb(main):008:0> Array(5..1)
=> []

Bunun nedeni aralık uygulamalarıdır.
Bu yüzden aşağıdaki seçeneği kullanmak zorunda kaldım:

(1..5).to_a.reverse

4
Bugün 5.downto(1).to_a, azalan bir aralığı ifade etmenin başka bir yolu olduğunu keşfettim stackoverflow.com/a/8927009/703903
odlp
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.