2010.01.15 10:15
przedwczoraj iterowałem i zastanawiałem się
Czasem trzeba przeiterować po wszystkich elementach jakiejś kolekcji. Wiele języków programowania ma do tego specjalne konstrukcje: foreach($kolekcja as $element), for element in kolekcja itp. Ale czasem trzeba przeiterować po elementach i odstępach między elementami (ja tak ostatnio miałem, jak robiłem konwerter do alfabetu morsa). Albo: przeiterować po zestawie (początek, pierwszy element, pierwsza przerwa, drugi element, druga przerwa, trzeci element, ..., ostatni element, koniec). Albo: przeiterować po zestawie (początek, pierwszy element parzysty, przerwa, pierwszy element nieparzysty, przerwa, drugi element parzysty, przerwa, ..., ostatni element (parzysty lub nie - bywa różnie), koniec). W żadnym znanym mi języku programowania nie ma specjalnych konstrukcji językowych do takich żądlerek. Ale można zastanowić się, jak by można w różnych językach ułatwić sobie takie dziwne iterowanie.
W PHP nie da się chyba inaczej, jak tylko zrobić funkcję, której daję tablicę (a, b, c, d), a ona zwraca tablicę (("typ"=>1, "element"=>a), ("typ"=>0, "przed"=>a, "po"=>b), ("typ"=>1, "element"=>b), ("typ"=>0, "przed"=>b, "po"=>c), ("typ"=>1, "element"=>c), ("typ"=>0, "przed"=>c, "po"=>d), ("typ"=>1, "element"=>d)). I potem już normalnie iterować po wyniku tej funkcji. Da się, choć w praktyce wychodzi to trochę nieczytelnie.
W JavaScripcie czy Pythonie, gdzie funkcje są pełnoprawnym typem, można by zrobić ładniej: stworzyć funkcję iteruj_dziwnie(kolekcja, kolbek_wolany_na_elementach, kolbek_wolany_na_odstepach). No ale przy takim rozwiązaniu każde wywołanie kolbeka odbywałoby się w osobnej przestrzeni nazw - a przecież czasem chcemy, żeby to, co robimy przy trzecim elemencie było prostą kontynuacją tego, co robiliśmy przy elemencie drugim. Na przykład jak coś tam sobie sumujemy czy coś. Wiem, da się to obejść, na przykład przez domknięcia lub (w Pythonie) przez dodanie funkcji argumentu, który jako domyślną wartość ma pustą tablicę. Ale takie sposoby są wykombinowane i sztuczne. Przydałoby się móc wywołując funkcję określić, na jakiej przestrzeni nazw ma zostać wykonana.
komentarze:
2010.01.15 12:24 Daniel
z cyklu \"jak iterować po różnych ciekawych rzeczach\" polecam common-lispową bibliotekę iterate:
http://common-lisp.net/project/iterate/
i moją bibliotekę do Clojure, inspirowaną nią:
http://github.com/nathell/clj-iter
2010.01.15 13:09 Piotrek
Wygląda ładnie. Muszę się werszcie clojure nauczyć.
powrót na stronę główną
RSS