Pętla ‘for each’

2008-02-09 20:17

W bardzo wielu językach dostępna jest dodatkowa postać pętli for, znana powszechnie jako foreach. Jak jej nazwa wskazuje, służy ona do przeglądania elementów jakiejś kolekcji. Różnica pomiędzy tą konstrukcją a dowolną inną pętlą jest taka, iż przeglądanie to jest zrealizowane w sposób najprostszy z możliwych:

  1. List<string> strings = new List<string>();
  2. // ...
  3. foreach (string s in strings)
  4.    Console.WriteLine (s);

W szczególności nie potrzeba się posługiwać żadnymi indeksami ani też jawnie stosowanymi iteratorami. Dostęp do poszczególnych elementów zbioru odbywa się za pośrednictwem symbolicznej zmiennej, która przyjmuje wartości równe tymże elementom. Proste i skuteczne.
Zresztą, niektórym twórcom języków tak się ta koncepcja spodobała, że… całkowicie zrezygnowali z tradycyjnej postaci pętli for (w wersji od-do, jak w Pascalu, lub start-warunek-inkrement, jak w językach C-podobnych).Tak jest chociażby w Pythonie; można tam jednak uzyskać identyczny efekt pętli “liczbowej” w taki oto zabawny sposób:

  1. # drukuje 0, ..., 9
  2. for i in range(0, 10):
  3.    print i

Ogółem jednak pętla foreach wydaje się bardzo zgrabnym wynalazkiem. Świadczy o tym chociażby istnienie takich makr jak BOOST_FOREACH, które to ładnie adaptuje cały pomysł do kontenerów STL w C++, tablic i nie tylko.
Jest jednak pewne ‘ale’. foreach sprawdza się świetnie, jeśli tylko kolekcję przeglądamy, bez dokonywania w niej zmian. Jeśli musimy przy okazji coś do niej dodać lub usunąć, lub nawet tylko zmienić wartość jakiegoś elementu, to nagle pętla taka przestaje nam wystarczać. Z doświadczenia wiem, że po tym, jak radośnie i bez wysiłku wpisuję pętlę foreach, w 80% muszę w którymś momencie i tak zmienić ją na zwykły for :-)

Tags: ,
Author: Xion, posted under Programming »


5 comments for post “Pętla ‘for each’”.
  1. nameczanin:
    February 10th, 2008 o 1:46

    Cóż za przemyślenia. Ja nawet w C# nie lubię tej pętli. Już zdecydowanie wolę tą z asm-a ;D

  2. Kurak:
    February 10th, 2008 o 16:33

    “lub nawet tylko zmienić wartość jakiegoś elementu, to nagle pętla taka przestaje nam wystarczać”

    short array_short[] = { 1, 2, 3 };
    BOOST_FOREACH( short & i, array_short )
    {
    ++i;
    }
    // array_short contains {2,3,4} here

    Jedyne co tu brzydko wygląda to “BOOST_FOREACH”, ktore zresztą u mnie nigdy nie występuje (#define foreach BOOST_FOREACH) ;>

  3. Xion:
    February 10th, 2008 o 18:14

    Kurak: W różnych językach jest z foreachami różnie. Np. w C# nie zmienisz wartości elementu tak jak powyżej, a już w Javie jest to możliwe.

  4. Kurak:
    February 10th, 2008 o 18:22

    Tak, ale w notce nic o tym nie wspomniałeś i wyglądało to tak, jakbyś uważał, że każdy foreach jest tylko do read-only :)

    Jeszcze ad BOOST_FOREACH – nie tylko do kontenerów STL :)

  5. Porke:
    February 11th, 2008 o 0:13

    Czasem istotnie foreach jest wygodniejszy, ale nierzadko potrzebuję zmiennej indeksowej do czegoś jeszcze w toku operacji wewnątrz pętli, acz do zwykłego ‘przebiegnięcia’ po elementach nadaje się znakomicie, w C# w takich przypadkach często przedkładam ją nad zwykłe for. Inna sprawa że for jak raz się napisze to później poprawiać nie trzeba, ale w przypadku wyspecyfikowania czego konkretnie się od kawałka kodu wymaga można uniknąć późniejszych modyfikacji. (tyle teoretycznie, a praktyka rządzi się własnymi prawami :P )

Comments are disabled.
 


© 2019 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.