Prawidłowy sposób na wypełnienie tablicy zakresem w Rubim

201

Pracuję nad książką, która podaje przykłady konwersji zakresów na równoważne tablice przy użyciu ich metod „to_a”

Kiedy uruchamiam kod w irb, pojawia się następujące ostrzeżenie

 warning: default `to_a' will be obsolete

Jaka jest poprawna alternatywa dla używania to_a?

czy istnieją alternatywne sposoby zapełniania tablicy zakresem?

Willbill
źródło
7
Dużym zastrzeżeniem dotyczącym konwersji zakresu na tablicę jest duży zasięg, który może zużywać dużo pamięci po zbudowaniu tablicy, więc używaj go ostrożnie. Zamiast tworzyć tablicę, lepszym rozwiązaniem może być iteracja w całym zakresie, tak jak w przypadku tablicy, aby zmniejszyć zużycie pamięci. Jest to jedna z tych rzeczy „stosuj w razie potrzeby”.
Tin Man

Odpowiedzi:

357

Możesz utworzyć tablicę z zakresem za pomocą ikony,

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

przy użyciu Kernel Arraymetody,

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

lub używając to_a

(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Zamith
źródło
1
Co jeśli tablica jest już utworzona i chcesz do niej dodać zakres: Mam order = 1. Potem order << (2.25).to_a. Ale to tworzy kolejną tablicę wewnątrz tablicy, po prostu chcę zakres od 2 do 25. Jednak jeśli spróbuję order << (2.25), otrzymam błąd, nie będę mógł przekonwertować zakresu na liczbę całkowitą.
kakubei
1
Używaj @kakubei concatzamiast <<. Ponadto nie powinieneś otrzymywać komunikatu „nie można przekonwertować zakresu na orderliczbę całkowitą”, chyba że jest to liczba całkowita - w takim przypadku przesuwałbyś bity, a nie dodawałeś tablicę.
Kelvin
3
opcja Splat nie działa dla Ruby 1.8.7, polecam użyć (1..10).to_adla kompatybilności wstecznej
kylewelsby
5
Twoje użycie ikony jest nieprzyjemne. Lepiej wygląda opcja [*1..10].
Hauleth
2
jaki jest najszybszy sposób?
Andrey Yasinishyn
79

Działa to dla mnie w irb:

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

Zauważam to:

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

Może brakuje Ci nawiasów?

(Korzystam z poziomu łatki Ruby 1.8.6 114)

Daniel Lucraft
źródło
7
Objaśnienie : bez nawiasów wywołujesz metodę to_a z instancji klasy Fixnum (w tym przypadku 4), a nie z zakresu 1..4. Jeśli korzystasz Fixnum.methods.include?(to_a)z Ruby 1.9.2, zauważysz, że metoda to_a nie jest już zdefiniowana, dlatego otrzymałeś ten komunikat o amortyzacji w 08
Pierre,
@Pierre Myślę, że miałeś na myśliFixnum.instance_methods.include?(:to_a)
Kelvin,
@Kelvin - W rzeczywistości methods.include?ma więcej informacji: $ irb irb(main):001:0> Fixnum.methods.include?(to_a) (irb):1: warning: default to_a 'będzie przestarzałe=> false irb(main):002:0> Fixnum.instance_methods.include?(:to_a) => false
Richard Turner
1
@RichardTurner Zakładam, że używasz Ruby 1.8. Obawiam się, że nie rozumiesz, co powoduje to_aostrzeżenie w pierwszej formie. To dlatego, że dzwonisz to_ana self- nie są faktycznie sprawdzenie, czy to_ajest to metoda Fixnum. Spróbuj zadzwonić to_asamodzielnie, a zobaczysz to samo ostrzeżenie.
Kelvin
@Kelvin - Duh! Grosz spada. Dzięki.
Richard Turner,
34

Wygląda na to, że to robisz:

0..10.to_a

Ostrzeżenie pochodzi od Fixnum # to_a, a nie z Range # to_a. Spróbuj zamiast tego:

(0..10).to_a
Richard Turner
źródło
9

Sprawdź to:

a = [*(1..10), :top, *10.downto( 1 )]
Boris Stitnicky
źródło
2
* 10.downto (1) było tym, czego szukałem, dziękuję!
Daniel
6

To jest inny sposób:

irb> [*1..10]

=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Jesús Andrés Valencia Montoya
źródło
4

Właśnie próbowałem użyć zakresów od większej do mniejszej i uzyskałem wynik, którego się nie spodziewałem:

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

Wynika to z implementacji zakresów.
Musiałem więc użyć następującej opcji:

(1..5).to_a.reverse
Nickolay Kondratenko
źródło
4
Dzisiaj odkryłem, 5.downto(1).to_aktóry jest innym sposobem wyrażenia malejącego zakresu stackoverflow.com/a/8927009/703903
odlp