PHP, pomimo wszystkich brodawek, jest całkiem niezłe pod tym względem. Nie ma różnicy między tablicą a skrótem (być może jestem naiwny, ale wydaje mi się to oczywiście w porządku) i iteracja po obu stronach
foreach (array/hash as $key => $value)
W Ruby istnieje wiele sposobów na zrobienie czegoś takiego:
array.length.times do |i|
end
array.each
array.each_index
for i in array
Hashe mają większy sens, ponieważ po prostu zawsze używam
hash.each do |key, value|
Dlaczego nie mogę tego zrobić dla tablic? Jeśli chcę zapamiętać tylko jedną metodę, myślę, że mogę jej użyć each_index
(ponieważ udostępnia ona zarówno indeks, jak i wartość), ale denerwujące jest to, że trzeba to robić array[index]
zamiast tylko value
.
No tak, zapomniałem o tym array.each_with_index
. Jednak ten jest do bani, ponieważ idzie |value, key|
i hash.each
idzie |key, value|
! Czy to nie jest szalone?
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?Odpowiedzi:
Spowoduje to iterację wszystkich elementów:
Wydruki:
Spowoduje to iterację wszystkich elementów podających wartość i indeks:
Wydruki:
Nie jestem do końca pewien twojego pytania, którego szukasz.
źródło
Myślę, że nie ma jednej właściwej drogi. Istnieje wiele różnych sposobów iteracji, a każda z nich ma swoją niszę.
each
jest wystarczający dla wielu zastosowań, ponieważ często nie dbam o indeksy.each_ with _index
działa jak Hash # każdy - dostajesz wartość i indeks.each_index
- tylko indeksy. Nie używam tego często. Odpowiednik „length.times”.map
to kolejny sposób iteracji, przydatny, gdy chcesz przekształcić jedną tablicę w drugą.select
jest iteratorem używanym, gdy chcesz wybrać podzbiór.inject
jest przydatny do generowania sum lub produktów lub zbierania pojedynczych wyników.To może wydawać się dużo do zapamiętania, ale nie martw się, możesz sobie poradzić nie znając ich wszystkich. Ale kiedy zaczniesz się uczyć i korzystać z różnych metod, twój kod stanie się bardziej przejrzysty i będziesz na najlepszej drodze do opanowania języka Ruby.
źródło
Nie twierdzę, że
Array
->|value,index|
iHash
->|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
albohash[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:
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:
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):
ale nie lubię robić (dla wstecz):
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):
i
co mi się nie podoba, ale ty nie możesz
Możesz ostatecznie zrobić
ale chcę uczyć czystego Rubiego zamiast podejść obiektowych (jeszcze). Chciałbym powtórzyć wstecz:
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.)
źródło
1.upto(10) do |i| puts i end
i w10.downto(1) do puts i end
pewnym sensie daje pożądaną symetrię. Mam nadzieję, że to pomaga. Nie jestem pewien, czy to zadziała dla łańcuchów i tym podobnych.[*1..10].each{|i| puts "i=#{i}" }
.Użyj each_with_index, gdy potrzebujesz obu.
źródło
Pozostałe odpowiedzi są w porządku, ale chciałem zwrócić uwagę na jeszcze jedną rzecz peryferyjną: tablice są uporządkowane, a skrótów nie ma w wersji 1.8. (W Ruby 1.9 hashe są uporządkowane według kolejności wstawiania kluczy.) Dlatego przed wersją 1.9 nie ma sensu iterowanie skrótu w taki sam sposób / sekwencję jak tablice, które zawsze miały określoną kolejność. Nie wiem, jaka jest domyślna kolejność dla tablic asocjacyjnych PHP (najwyraźniej moje google fu też nie jest wystarczająco silne, aby to rozgryźć), ale nie wiem, jak można rozważyć zwykłe tablice PHP i tablice asocjacyjne PHP, aby być „tym samym” w tym kontekście, ponieważ kolejność tablic asocjacyjnych wydaje się nieokreślona.
Jako taki, sposób Ruby wydaje mi się bardziej przejrzysty i intuicyjny. :)
źródło
Próba zrobienia tego samego konsekwentnie z tablicami i skrótami może być po prostu zapachem kodu, ale ryzykując, że zostanę uznany za korsarza pół-małpiego patchera, jeśli szukasz spójnego zachowania, to załatwi sprawę ?:
źródło
Oto cztery opcje wymienione w twoim pytaniu, ułożone według wolności kontroli. Możesz użyć innego, w zależności od tego, czego potrzebujesz.
Po prostu przejdź przez wartości:
Wystarczy przejrzeć indeksy:
Przejdź przez indeksy + zmienną indeksu:
Liczba pętli kontrolnych + zmienna indeksu:
źródło
Próbowałem zbudować menu (w Camping i Markaby ) przy użyciu skrótu.
Każdy element ma 2 elementy: etykietę menu i adres URL , więc hash wydawał się odpowiedni, ale „/” URL „Home” zawsze pojawiał się jako ostatni (jak można się spodziewać po haszu), więc elementy menu pojawiały się w niewłaściwym miejscu zamówienie.
Użycie tablicy z
each_slice
wykonuje zadanie:Dodanie dodatkowych wartości do każdego elementu menu (np. Jak nazwa identyfikatora CSS ) oznacza po prostu zwiększenie wartości plasterka. Tak jak skrót, ale z grupami składającymi się z dowolnej liczby elementów. Doskonały.
To dlatego dziękuję za nieumyślne wskazanie rozwiązania!
Oczywiste, ale warte stwierdzenia: sugeruję sprawdzenie, czy długość tablicy jest podzielna przez wartość wycinka.
źródło
Jeśli używasz wymiennego mixina (podobnie jak Rails), możesz zrobić coś podobnego do wymienionego fragmentu php. Wystarczy użyć metody each_slice i spłaszczyć skrót.
Wymagane jest mniej łatania małp.
Powoduje to jednak problemy, gdy masz tablicę rekurencyjną lub skrót z wartościami tablic. W Ruby 1.9 problem ten został rozwiązany za pomocą parametru metody spłaszczania, który określa, jak głęboko ma się powtarzać.
Jeśli chodzi o pytanie, czy to zapach kodu, nie jestem pewien. Zwykle, gdy muszę pochylić się do tyłu, aby powtórzyć coś, cofam się i zdaję sobie sprawę, że źle atakuję problem.
źródło
Właściwy sposób to taki, w którym czujesz się najlepiej i który robi to, co chcesz. W programowaniu rzadko jest jeden „poprawny” sposób robienia rzeczy, częściej istnieje wiele sposobów wyboru.
Jeśli czujesz się dobrze z pewnym sposobem robienia rzeczy, rób to, chyba że to nie działa - to czas znaleźć lepszy sposób.
źródło
W Ruby 2.1 metoda each_with_index jest usuwana. Zamiast tego możesz użyć each_index
Przykład:
produkuje:
źródło
each_with_index
nie pojawia się w dokumentacji, ponieważ została podana przezEnumerable
moduł.Zastosowanie tej samej metody do iteracji zarówno tablic, jak i skrótów ma sens, na przykład do przetwarzania zagnieżdżonych struktur skrótów i tablic często wynikających z analizatorów składni, odczytu plików JSON itp.
Jednym sprytnym sposobem, o którym jeszcze nie wspomniano, jest to, jak to się dzieje w bibliotece standardowych rozszerzeń biblioteki Ruby Facets . Od tutaj :
Istnieje już
Hash#each_pair
aliasHash#each
. Więc po tej łatce mamy jąArray#each_pair
i możemy używać zamiennie do iteracji zarówno skrótów, jak i tablic. To naprawia zaobserwowane szaleństwo PO, któreArray#each_with_index
odwraca argumenty blokowe w porównaniu doHash#each
. Przykładowe użycie:źródło