Pętle są fundamentem wielu algorytmów i operacji w programowaniu, umożliwiając wielokrotne wykonywanie określonych instrukcji. Tworząc aplikacje na platformie Ferryt mamy do dyspozycji różne rodzaje pętli, takie jak for, while, do-while oraz foreach. Korzystanie z pętli możliwe jest zarówno z poziomu kontrolki przepływu „pętla” BPM jak i z poziomu reguły, gdzie pętle można napisać z wykorzystaniem składni C# w edytorze zaawansowanym.
Wydajność tych pętli może mieć znaczący wpływ na ogólną szybkość i efektywność działania aplikacji. W tym artykule omówimy, jak pisać pętle w regułach używając edytora zaawansowanego oraz jak sprawić aby taka pętla była wydajna, przedstawiając przykłady i najlepsze praktyki.
Pętla for
Pętla for jest jedną z najczęściej używanych pętli w programowaniu. Umożliwia precyzyjne kontrolowanie liczby iteracji dzięki określeniu warunku początkowego, końcowego oraz kroku iteracji (modyfikacji).
Przykład podstawowej pętli for
for (int i = 0; i < PF.WplatyKlienta.Length; i++)
{
PF.SumaWplat += PF.WplatyKlienta[i];
}
Ten przykład ilustruje podstawową pętlę for, która iteruje po wpłatach klienta i sumuje jego wszystkie wpłaty w polu PF.SumaWplat. Przyjrzyjmy się teraz szczegółowo każdemu elementowi tej pętli:
- Inicjalizacja (
int i = 0;): W tej części deklarujemy i inicjalizujemy zmiennąi, która będzie używana jako licznik pętli. Pętla rozpoczyna się od wartości0, co oznacza, że w pierwszej iteracji indeks pierwszej wpłaty będzie wynosił0. - Warunek (
i < PF.WplatyKlienta.Length;): Jest to kluczowy element, który kontroluje, jak długo pętla będzie się wykonywać. Pętla będzie się kontynuowała, dopóki zmiennaijest mniejsza niż długość tablicyWplatyKlienta. Gdyiosiągnie wartość równą długości tej tablicy, pętla zakończy swoje działanie. - Modyfikacja (krok iteracji) (
i++): Ta część kodu jest wykonywana po każdej iteracji pętli.i++oznacza, że wartośćijest zwiększana o 1 po każdej iteracji. Dzięki temu pętla przetwarza każdą wpłatę z tablicyWplatyKlienta.
Możliwości konfiguracji elementów Pętli for
- Inicjalizacja: Możesz zainicjalizować wiele zmiennych lub użyć zmiennych już istniejących:
int indexSymulacji = 0;
for (int i = PF.IlosSplaconychRat, j = PF.IloscPozostalychRat; i < j; i++, j--)
{
PF.Symalacja(indexSymulacji)($"ilość spłaconych rat: {i}, Ilość pozostałych rat: {j}");
indexSymulacji ++
}
W tym przypadku i rośnie, a j maleje z każdą iteracją.
- Warunki: Możesz użyć bardziej złożonych warunków logicznych:
for (int i = 0; i < PF.WplatyKlienta.Length && PF.WplatyKlienta[i] >= 0; i++)
{
PF.SumaWplat += PF.WplatyKlienta[i];
}
Pętla kończy się, gdy napotkamy pierwszą ujemną wpłatę.
- Modyfikacja (krok iteracji): Możesz zastosować różne operacje modyfikacji, niekoniecznie inkrementację:
for (int i = 0; i < PF.WplatyKlienta.Length; i += 2)
{
PF.SumaWplat += PF.WplatyKlienta[i];
}
W tym przykładzie przetwarzamy co drugą wpłatę, co może być użyteczne w specyficznych przypadkach.
Dobre praktyki dla pętli for
- Optymalizacja warunku końcowego: Sprawdzenie warunku końcowego powinno być jak najmniej kosztowne, np. poprzez przechowywanie długości tablicy w zmiennej lokalnej.
- Minimalizowanie operacji wewnątrz pętli: Unikaj skomplikowanych operacji w ciele pętli, przenieś je na zewnątrz, jeśli to możliwe. Najprościej rzecz ujmując jeżeli jakaś logika może dziać się poza pętlą, nie jest wymagana powtarzania jej wykonania, powinna ona się znaleźć poza pętlą.
Przykład mało wydajny:
for (int i = 0; i < (PF.WplatyKlienta.Length - 2); i++)
{
PF.ImieNazwiskoKlienta = "Adam Kowal";
PF.SumaWplat += PF.WplatyKlienta[i];
}
Przykład bardziej wydajny:
int SkorygowanaLiczbaWplat = PF.WplatyKlienta.Length - 2;
for (int i = 0; i < SkorygowanaLiczbaWplat (); i++)
{
PF.SumaWplat += PF.WplatyKlienta[i];
}
PF.ImieNazwiskoKlienta = "Adam Kowal";
W powyższym przykładzie zapisaliśmy skorygowaną długość tablicy WplatyKlienta - 2 do zmiennej SkorygowanaLiczbaWplat, co pozwala na unikanie wielokrotnego wywoływania operacji PF.WplatyKlienta.Length - 2 w każdej iteracji. Dodatkowo operacje przypisania imienia i nazwiska klienta do pola PF.ImieNazwiskoKlienta , która nie jest zależna od pętli przenieśliśmy poza pętle, aby nie wykonała się wielokrotnie.

Pętla while
Pętla while kontynuuje wykonywanie swojego ciała, dopóki warunek jest prawdziwy. Jest używana, gdy nie wiemy dokładnie, ile iteracji będzie potrzebnych z góry.
Przykład podstawowej pętli while
Rozważmy ten sam przykład sumowania wpłat klienta:
int i = 0;
while (i < PF.WplatyKlienta.Length)
{
PF.SumaWplat += PF.WplatyKlienta[i];
i++;
}
Ta pętla while działa podobnie do pętli for, ale różni się nieco strukturą. Oto szczegółowa analiza:
- Inicjalizacja (
int i = 0;): Zmiennaijest inicjalizowana przed rozpoczęciem pętli. - Warunek (
i < PF.WplatyKlienta.Length): Pętla będzie się wykonywać tak długo, jak długoibędzie mniejsze niż liczba wpłat klienta. - Modyfikacja (
i++): W przeciwieństwie do pętlifor, tutaj musimy ręcznie zwiększać wartośćiwewnątrz ciała pętli, aby uniknąć nieskończonej pętli.
Dobre praktyki dla pętli while
- Upewnienie się, że warunek zakończenia jest osiągalny: Aby uniknąć nieskończonych pętli, warunek zakończenia musi być osiągalny.
- Unikanie nieskończonych pętli: Zawsze sprawdzaj, czy pętla może się zakończyć, by nie blokować programu.
- Minimalizowanie operacji wewnątrz pętli: Unikaj skomplikowanych operacji w ciele pętli, przenieś je na zewnątrz, jeśli to możliwe. Najprościej rzecz ujmując jeżeli jakaś logika może dziać się poza pętlą, nie jest wymagana powtarzania jej wykonania, powinna ona się znaleźć poza pętlą.
Pętla do-while
Pętla do-while jest podobna do pętli while, z tą różnicą, że sprawdzenie warunku następuje po wykonaniu ciała pętli. Dzięki temu pętla do-while jest gwarantowana do wykonania co najmniej raz.
Przykład podstawowej pętli do-while
Rozważmy scenariusz, w którym musimy przynajmniej raz przetworzyć wpłaty klienta:
int i = 0;
do
{
PF.SumaWplat += PF.WplatyKlienta[i];
i++;
} while (i < PF.WplatyKlienta.Length);
Pętla ta sumuje wpłaty, przynajmniej raz wykonując swoje ciało. Szczegóły:
- Inicjalizacja (
int i = 0;): Zmiennaijest inicjalizowana przed rozpoczęciem pętli. - Warunek (
i < PF.WplatyKlienta.Length): Warunek sprawdzany jest po wykonaniu ciała pętli, co gwarantuje przynajmniej jedno wykonanie. - Modyfikacja (
i++): Zmiennaijest zwiększana po każdej iteracji, co zapewnia przejście do kolejnej wpłaty.
Pętla do-while jest użyteczna, gdy chcemy, aby pętla wykonała się przynajmniej raz, niezależnie od początkowego warunku. W opisanym przypadku mamy pewność, że przynajmniej jedna wpłata klienta zostanie przetworzona i dodana do sumy, nawet jeśli tablica WplatyKlienta zawiera tylko jeden element.

Pętla foreach
Pętla foreach jest doskonałym narzędziem do iterowania przez kolekcje, takie jak tablice, listy czy inne zbiory danych. Jest szczególnie przydatna, gdy chcemy przechodzić przez wszystkie elementy kolekcji bez potrzeby manipulowania indeksem, co upraszcza kod i zmniejsza ryzyko błędów.
Przykład podstawowej pętli foreach
Rozważmy przykład, w którym mamy listę wpłat klienta i chcemy obliczyć ich sumę. Używając pętli foreach, możemy przechodzić przez każdą wpłatę w tej kolekcji i sumować je bez potrzeby martwienia się o indeksowanie.
foreach (decimal wplata in PF.WplatyKlienta)
{
PF.sumaWplat += wplata;
}
Analiza Przykładu:
- Struktura pętli
foreach:foreach (decimal wplata in PF.WplatyKlienta)– Dla każdej wpłaty (wplata) w kolekcjiPF.WplatyKlientapętla wykonuje swoje ciało.wplatato zmienna, która przechowuje aktualnie przetwarzany element kolekcji podczas każdej iteracji.
- Dodawanie każdej wpłaty do sumy:
sumaWplat += wplata;– Każda wpłata jest dodawana do zmiennejsumaWplat, co pozwala na obliczenie łącznej sumy wszystkich wpłat.
Dobre Praktyki dla Pętli foreach
- Ochrona przed modyfikacją kolekcji: W pętli
foreachnie można modyfikować kolekcji, przez którą iterujemy (np. dodawać lub usuwać elementów), co zapobiega potencjalnym błędom.
- Efektywność w przetwarzaniu dużych kolekcji: Pętla
foreachjest zoptymalizowana pod kątem efektywnego iterowania przez kolekcje, co czyni ją dobrym wyborem do przetwarzania dużych zbiorów danych, zwłaszcza jeśli nie musimy manipulować kolejnością lub pozycją elementów.

Zagnieżdżanie pętli
Zagnieżdżanie pętli to technika, która pozwala na wykonywanie iteracji wielowymiarowych, czyli przetwarzanie danych na wielu poziomach jednocześnie. Dzięki temu podejściu system wykonuję „pętle w pętli”, dzięki czemu możemy skupić się na przetwarzaniu tylko tych danych, które są istotne, co zwiększa wydajność i przejrzystość kodu.
Załóżmy, że mamy listę rachunków klienta, z której każda pozycja zawiera informacje o statusie konta i jego wpłatach. Pierwsza pętla for iteruje po rachunkach, sprawdzając, czy są otwarte, a druga pętla for, zagnieżdżona wewnątrz pierwszej, sumuje wpłaty na danym koncie, jeśli jest ono otwarte. W kontekście tego przykładu możemy zagnieździć pętle, aby iterować po rachunkach klienta i przetwarzać wpłaty tylko na otwartych kontach.
for (int i = 0; i < PF.klient.Rachunki.Length; i++)
{
if (PF.klient.Rachunki[i].CzyOtwarte)
{
for (int j = 0; j < PF.klient.Rachunki[i].Wplaty.Length; j++)
{
PF.sumaWplatWszystkichKont += PF.klient.Rachunki[i].Wplaty[j];
}
}
}
Analiza Przykładu:
- Pętla zewnętrzna (
for):for (int i = 0; i < PF.klient.Rachunki.Length; i++)– Przechodzimy przez wszystkie rachunki klienta.
- Warunek sprawdzający otwartość rachunku:
if (PF.klient.Rachunki[i].CzyOtwarte)– Sprawdzamy, czy dany rachunek jest otwarty. Jeśli tak, przechodzimy do sumowania wpłat.
- Pętla wewnętrzna (
for):for (int j = 0; j < PF.klient.Rachunki[i].Wplaty.Length; j++)– Przechodzimy przez wszystkie wpłaty na danym rachunku, jeśli jest otwarty.
- Sumowanie wpłat:
PF.sumaWplatWszystkichKont += PF.klient.Rachunki[i].Wplaty[j];– Dodajemy każdą wpłatę z otwartego rachunku do łącznej sumy wpłat wszystkich kont.
Podsumowanie
Umiejętność odpowiedniego wyboru i efektywnego wykorzystania pętli jest kluczowa dla każdego Ferryt Developera. Dobór odpowiedniej pętli oraz dbanie o dobre praktyki wpływa nie tylko na wydajność aplikacji, ale także na jej czytelność i łatwość utrzymania. Dzięki zrozumieniu różnych typów pętli oraz przestrzeganiu dobrych praktyk, można tworzyć bardziej niezawodny i zoptymalizowany kod, co jest szczególnie istotne w zaawansowanych aplikacjach, które przetwarzają duże ilości danych.
2 Comments
herba
Super, wiedza na pewno przydatna w pracy z Ferrytem:)
Izabella Guzińska
Dobrze mieć to wszystko spisane w jednym miejscu. Bardzo przydatna alternatywa w stosunku do pętli ferrytowych 🙂