Nie twierdzę, że Array
-> |value,index|
i Hash
-> |key,value|
nie jest szalone (patrz komentarz Horace'a Loeba), ale mówię, że istnieje rozsądny sposób, aby spodziewać się takiego rozwiązania.
Kiedy mam do czynienia z tablicami, koncentruję się na elementach tablicy (nie na indeksie, ponieważ indeks jest przejściowy). Każda metoda ma indeks, tzn. Każdy + indeks lub | każdy, indeks | lub |value,index|
. Jest to również spójne z indeksem postrzeganym jako opcjonalny argument, np. | Wartość | jest równoważne | wartości, indeks = zero | co jest zgodne z | wartością, indeksem |.
Kiedy mam do czynienia z mieszań, jestem często bardziej koncentruje się na klawiszach od wartości, a ja zwykle do czynienia z kluczy i wartości w tej kolejności, albo key => value
albo hash[key] = value
.
Jeśli chcesz pisać na kaczce, albo jawnie użyj zdefiniowanej metody, jak pokazał Brent Longborough, lub metody niejawnej, jak pokazał maxhawkins.
Ruby polega na dostosowywaniu języka do potrzeb programisty, a nie na dostosowywaniu programisty do języka. Dlatego jest tak wiele sposobów. Jest wiele sposobów myślenia o czymś. W Ruby wybierasz najbliższy, a reszta kodu zwykle wypada wyjątkowo starannie i zwięźle.
Jeśli chodzi o pierwotne pytanie: „Jaki jest„ właściwy ”sposób na iterację w tablicy w Rubim?”, Myślę, że głównym sposobem (tj. Bez potężnego cukru syntaktycznego lub mocy obiektowej) jest:
for index in 0 ... array.size
puts "array[#{index}] = #{array[index].inspect}"
end
Ale w Ruby chodzi o potężny cukier syntaktyczny i moc obiektową, ale w każdym razie jest to odpowiednik skrótów, a klucze można zamówić lub nie:
for key in hash.keys.sort
puts "hash[#{key.inspect}] = #{hash[key].inspect}"
end
Zatem moja odpowiedź brzmi: „„ Właściwy ”sposób iteracji w tablicy w Ruby zależy od ciebie (tj. Programisty lub zespołu programistów) i projektu.” Im lepszy programista Ruby, tym lepszy wybór (która moc syntaktyczna i / lub które podejście obiektowe). Lepszy programista Ruby nadal szuka innych sposobów.
Teraz chcę zadać kolejne pytanie: „Jaki jest„ właściwy ”sposób na iterację wsteczną przez zakres w Ruby?”! (To pytanie, jak doszedłem do tej strony).
Miło jest zrobić (dla napastników):
(1..10).each{|i| puts "i=#{i}" }
ale nie lubię robić (dla wstecz):
(1..10).to_a.reverse.each{|i| puts "i=#{i}" }
Cóż, właściwie nie mam nic przeciwko robieniu tego zbyt wiele, ale kiedy uczę cofania się, chcę pokazać moim uczniom niezłą symetrię (tj. Z minimalną różnicą, np. Dodając tylko odwrotność lub krok -1, ale bez modyfikowanie czegokolwiek innego). Możesz zrobić (dla symetrii):
(a=*1..10).each{|i| puts "i=#{i}" }
i
(a=*1..10).reverse.each{|i| puts "i=#{i}" }
co mi się nie podoba, ale ty nie możesz
(*1..10).each{|i| puts "i=#{i}" }
(*1..10).reverse.each{|i| puts "i=#{i}" }
#
(1..10).step(1){|i| puts "i=#{i}" }
(1..10).step(-1){|i| puts "i=#{i}" }
#
(1..10).each{|i| puts "i=#{i}" }
(10..1).each{|i| puts "i=#{i}" } # I don't want this though. It's dangerous
Możesz ostatecznie zrobić
class Range
def each_reverse(&block)
self.to_a.reverse.each(&block)
end
end
ale chcę uczyć czystego Rubiego zamiast podejść obiektowych (jeszcze). Chciałbym powtórzyć wstecz:
- bez tworzenia tablicy (rozważ 0..1000000000)
- praca dla dowolnego zakresu (np. ciągów, nie tylko liczb całkowitych)
- bez użycia dodatkowej mocy obiektowej (tj. bez modyfikacji klasy)
Uważam, że jest to niemożliwe bez zdefiniowania pred
metody, co oznacza modyfikację klasy Range, aby z niej korzystać. Jeśli możesz to zrobić, proszę dać mi znać, w przeciwnym razie potwierdzenie niemożliwości byłoby mile widziane, ale byłoby rozczarowujące. Być może Ruby 1.9 rozwiązuje ten problem.
(Dziękujemy za poświęcony czas na przeczytanie tego.)
array#each_with_index
używa,|value, key|
ponieważ nazwa metody implikuje kolejność, podczas gdy kolejność stosowana dohash#each
naśladowaniahash[key] = value
składni?