Pętla foreach

Z Wikipedii, wolnej encyklopedii
Skocz do: nawigacja, szukaj

Pętla foreach, pętla "po kolekcji" — w programowaniu rodzaj pętli, której wykonanie polega na powtarzaniu kolejnych iteracji dla wszystkich elementów (komórek) wybranego agregatu danych, takiego jak, np. tablica, lista, kolekcja, kolejka lub innego, dostępnego w danym języku programowania, bądź jego konkretnej implementacji. Pętla taka automatycznie przed przejściem do wykonania kolejnej iteracji przypisuje zadanej w nagłówku pętli zmiennej sterującej wartość kolejnego elementu (komórki).

Składnia[edytuj | edytuj kod]

Składnia zapisu tego rodzaju pętli jest różna w poszczególnych językach programowania, lecz można wyodrębnić pewne ogólne, charakterystyczne zasady:

  1. na początku definicji pętli zwykle występuje słowo kluczowe identyfikujące pętlę; są to słowa for each (np. Visual Basic[1], VBA[2]), lub pisane łącznie jedno słowo foreach (np. D[3], PHP[4]); rzadziej słowo for i słowo foreach stanowią synonim i mogą być używane zamiennie, zarówno w pętli ogólnej, jak i w pętli "po kolekcji" (np. Perl[5]), lub inne
  2. następnie specyfikowana jest zmienna sterująca
  3. za nią często spotkać można słowo łączące, np. in
  4. dalej definiowany jest agregat danych, dla którego ma być wykonywana pętla,
  5. ewentualnie w niektórych językach występuje kolejne słowo łączące, zamykające definicję pętli, np. do.

Natomiast składnia tej pętli, w tych językach, w których występuje pętla ogólna, często wzorowana jest na składni tej pętli. W tym przypadku zamiast słów łączących stosuje się nawiasy i średniki.

Działanie[edytuj | edytuj kod]

Działanie tej pętli polega na wykonaniu następujących kroków:

  1. ustal jako bieżący, pierwszy element kontenera danych, jeżeli kontener jest pusty, zakończ działanie pętli
  2. przypisz wartość bieżącego elementu do zmiennej sterującej
  3. wykonaj iterację
  4. sprawdź czy istnieje kolejny ("następny") element w kontenerze:
    jeżeli istnieje, to ustal jako bieżący ten kolejny element kontenera i przejdź do punktu 2
    jeżeli nie istnieje to zakończ wykonywanie pętli.

Pętla foreach w językach programowania[edytuj | edytuj kod]

Pętla tego typu dostępna jest w nowszych językach, w szczególności w językach zorientowanych na programowanie obiektowe, w których zrealizowano dynamiczne struktury danych. Również w kolejnych implementacjach języków, w których nie było tego rodzaju pętli, wprowadza się ją, szczególnie wraz z wprowadzaniem nowych kontenerów danych dostępnych standardowo w nowych implementacjach.

Pętla foreach w językach programowania
język programowania składnia
Ada[6][7]
for zmienna-sterująca in [reverse] kontener-typ-lub-zakres [range zakres] loop 
  -- instrukcje 
end loop;
D[3]
foreach(zmienna-sterująca; kontener) /* instrukcja */;
JavaScript[8][9]
for (zmienna-sterująca in kontener) /* instrukcja */;
Perl[5]
foreach zmienna-sterująca (kontener) { 
  # instrukcje 
 }
for zmienna-sterująca (kontener) { 
  # instrukcje 
 }
[a]
PHP[4]
foreach(kontener as zmienna-sterująca) { 
  /* instrukcje */ }
Python[10]
for zmienna-sterująca in kontener:
  # instrukcje
Visual Basic[1], VBA[2]
For Each zmienna-sterująca In kontener 
  ' instrukcje 
Next zmienna-sterująca
Uwaga: nawiasy kwadratowe obejmują frazy opcjonalne

Porównanie z innymi konstrukcjami[edytuj | edytuj kod]

Pętlę foreach można zaimplementować za pomocą innych konstrukcji dostępnych w danym języku programowania. Pętla ta została wprowadzona do języków programowania lub ich kolejnych, nowszych implementacji jako rozwinięcie wcześniej stosowanych pętli, jako konstrukcja działająca na wyższym poziomie abstrakcji, która czytelniej dla programisty oddaje sens wykonywanych operacji oraz uwalnia go od konieczności jawnego kodowania mało istotnych szczegółów realizacyjnych. Zapis tej pętli jest zapisem samo dokumentującego się kodu źródłowego programu.

Realizacja pętli foreach za pomocą instrukcji warunkowej i skoku[edytuj | edytuj kod]

Za pomocą instrukcji warunkowej i skoku można zrealizować każdą pętlę, także pętlę "po kolekcji". Widoczna jest jednak nieczytelność takiego kodu w porównaniu do pętli foreach, realizującej zadanie na znacznie wyższym poziomie abstrakcji.

Pętla foreach - instrukcja warunkowa i skoku
Visual Basic[1], VBA[2]
foreach if, goto
For Each I In Kontener 
  ' instrukcje 
Next I
Ix=1
LenK=Kontener.Len
start: If Ix>LenK then Goto koniec
  I=Kontener.Item(Ix)
  ' instrukcje 
  Ix=Ix+1
Goto start
koniec:

Realizacja pętli foreach za pomocą pętli repetycyjnej[edytuj | edytuj kod]

Pętla repetycyjna w porównaniu z instrukcją warunkową i skoku pozwana nieco czytelniej zrealizować zadnie pętli foreach, lecz nadal trzeba kodować wiele dodatkowych czynności, realizowanych w pętli "po kolekcji" niejawnie.

Pętla foreach - instrukcja repetycyjna
Visual Basic[1], VBA[2]
foreach repetycyjna
For Each I In Kontener 
  ' instrukcje 
Next I
Ix=1
LenK=Kontener.Len
Do While Ix<=LenK
  I=Kontener.Item(Ix)
  ' instrukcje 
  Ix=Ix+1
Loop

Realizacja pętli foreach za pomocą pętli iteracyjnej[edytuj | edytuj kod]

Realizacja pętli foreach za pomocą pętli iteracyjnej jest łatwa i przejrzysta, pod warunkiem, że istnieje mechanizm badania liczby elementów kontenera danych, niezbędny od ustalenia liczby powtórzeń, lub badania wartości granicznych (granicy dolnej i górnej) indeksów elementów kontenera danych. Szczególną analogię można dostrzec pomiędzy instrukcją foreach a instrukcją iteracyjnych w tych językach programowania, w których instrukcja iteracyjna ma składnię taką jak foreach, tzn. w których określamy, że zmienna sterująca ma przyjmować kolejne wartości podanego zakresu, tak jak to ma miejsce np. w języku Ada[6][7] (for i in w1..w2 loop ... end loop;). Pętla ta ma możliwość zresztą wykonywania iteracji np. dla wszystkich wartość określonego typu danych lub dla wszystkich komórek tablicy: for i in typ_danych-lub-tablica loop ... end loop;, także dla zakresu: for i in typ_danych range w1..w2 loop ... end loop;, for i in tablica'range(x) loop ... end loop;, oraz w odwrotnej kolejności (modyfikator reverse): for i in reverse typ_danych-lub-tablica loop ... end loop;; co w dużym stopniu klasyfikuje tę pętlę jako pętlę zarówno iteracyjną jak i przede wszystkim "po kolekcji"[6][7].

Pętla foreach - instrukcja iteracyjna
Visual Basic[1], VBA[2] Ada[6][7]
foreach iteracyjna foreach iteracyjna
For Each I In Kontener 
  ' instrukcje 
Next I
LenK=Kontener.Len
For Ix=1 To LenK
  I=Kontener.Item(Ix)
  ' instrukcje 
Next Ix
for I in Kontener loop
  -- instrukcje 
end loop
ws:=Kontener'First
wp:=Kontener'Last
for Ix in ws..wp loop
  I=Kontener(Ix)
  -- instrukcje 
end loop

Realizacja pętli foreach za pomocą pętli ogólnej[edytuj | edytuj kod]

Również pętla ogólna umożliwia implementację pętli foreach na zasadach takich jak dla pętli iteracyjnej (iterowanie po kolejnych indeksach kontenera danych), i repetycyjnej (jawny zapis warunku pętli).

Pętla foreach - instrukcja ogólna
D[3]
foreach ogólna
foreach(I; Kontener) 
 {
   /* instrukcje */
 }
for(Ix=0; Ix<Kontener.length; Ix++) 
 {
   I=Kontener[Ix];
   /* instrukcje */
 }

Uwagi

  1. Ze względu na czytelność kodu i dobry styl programowania, nie zaleca się stosować słowa for dla pętli "po kolekcji" lecz słowo foreach, a słowo for zaleca się stosować dla pętli ogólnej.

Przypisy

  1. 1,0 1,1 1,2 1,3 1,4 Podręcznik Visual Basic na Wikibooks
  2. 2,0 2,1 2,2 2,3 2,4 John Walkenbach: Excel 2003 PL. Programowanie w VBA.. HELION, 2004. ISBN 837361-504-0. (pol.)
  3. 3,0 3,1 3,2 Podręcznik języka D na Wikibooks
  4. 4,0 4,1 Podręcznik języka PHP na Wikibooks
  5. 5,0 5,1 Podręcznik języka Perl na Wikibooks
  6. 6,0 6,1 6,2 6,3 A. Nico Habermann, Dewayne E. Perry: Ada dla zaawansowanych. Warszawa: Wydawnictwa Naukowo-Techniczne, 1989, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-204-1058-4. (pol.)
  7. 7,0 7,1 7,2 7,3 Michał Morawski, Antoni M. Zajaczkowski: Wstep do programowania w jezyku Ada’95. Wyd. drugie. Łódz: 2004. [dostęp 2011-01-29]. (pol.)
  8. Wojciech Romowicz: HTML i JavaScript. HELION, 1998. ISBN 83-7197-046-3. (pol.)
  9. Kurs języka JavaScript (pol.). Poradnik Webmastera. [dostęp 2011-02-09].
  10. Podręcznik języka Python na Wikibooks