Na pewno każdy zna pętlę foreach od DarkGL'a, a jak nie to tu macie link:
https://amxx.pl/topi...iających-życie/
Wszystko fajnie, tylko kiedy próbuje się operować na zmiennych rzeczywistych jest ostrzeżenie takie: "Warning: Tag mismatch on line 99".
Nic takiego się złego nie dzieje, ale raczej nikt nie chce mieć takich ostrzeżeń w kompilatorze bo czasem mógłby ktoś faktycznie mieć poważny problem związany z tym błedem
#define foreach(%1,%2) for(new array_size=sizeof %1, i=0 , %2=%1[0]; i<array_size ; i++, %2=i<array_size? %1[i]:any:0)Tu jest poprawiona wersja, wystarczyło wpisać "any:" przed ostatnim zerem
Zrobiłem jeszcze dodatkowo 3 podobne funkcje do obsługi tablic dynamicznych:
#define dynamic_foreach(%1,%2) for(new array_size=ArraySize(%1), %2=ArrayGetCell(%1, 0), i=0; i<array_size; i++, %2=i<array_size? ArrayGetCell(%1, i):any:0) #define dynamic_string_foreach(%1,%2,%3) for(new array_size=ArraySize(%1), %2[%3], i=0&ArrayGetString(%1, 0, %2, %3-1); i<array_size; i++, i<array_size? ArrayGetString(%1, i, %2, %3-1):0) #define dynamic_array_foreach(%1,%2,%3) for(new array_size=ArraySize(%1), %2[%3], i=0&ArrayGetArray(%1, 0, %2); i<array_size; i++, i<array_size? ArrayGetArray(%1, i, %2):0)Opis i użycie:
1. dynamic_foreach(%1,%2)
Działanie takie samo jak foreach tylko, że na tablicach dynamicznych
%1 - uchwyt tablicy dynamicznej
%2 - zmienna do której mają zapisywać się po kolei kolejne rekordy
2. dynamic_string_foreach(%1,%2,%3)
Pobiera kolejne napisy z tablicy dynamicznej i zapisuje je do naszej tablicy, która ma przechowywać napis
%1 - uchwyt tablicy dynamicznej
%2 - tablica do której będą zapisywane kolejne napisy
%3 - wielkość tablicy do której mają być zapisane napisy
3. dynamic_array_foreach(%1,%2,%3)
Pobiera kolejne tablice zapisane w tablicy dynamicznej i zapisuje je do naszej tablicy
%1 - uchwyt tablicy dynamicznej
%2 - tablica do której mają być zapisane kolejne tablice
%3 - wielkość tablicy
Kolejną bardzo fajną funkcją jest "explode", link:
https://amxx.pl/topic/43223-explode/
rozdziela jeden napis na kilka innych, które są oddzielone podanym znakiem...
Oryginalny kod zrobiony przez DarkGL:
stock explode(const string[],const character,output[][],const maxs,const maxlen) { new iDo = 0, len = strlen(string), oLen = 0; do{ oLen += (1+copyc(output[iDo++],maxlen,string[oLen],character)) }while(oLen < len && iDo < maxs) }Zupełnie nic tu nie zmieniałem bo kod działa idealnie tak jak miał działać.
Jedyne co zrobiłem to funkcja "explode_num", która częściej mi się przydawała.
Działanie jest podobne, ale nie zwraca tablicy z napisami, tylko tablicę z liczbami całkowitymi (brak sprawdzania czy napis to liczba bo raczej programista wie co robi)
stock explode_num(const string[],const character,output[],const maxs) { new iDo = 0, len = strlen(string), oLen = 0, num[32]; do{ oLen += (1+copyc(num,charsmax(num),string[oLen],character)); output[iDo++] = str_to_num(num); }while(oLen < len && iDo < maxs) }string - napis, który ma zostać rozdzielony
character - znak, który rozdziela napisy
output - tablica z liczbami
maxs - wielkość tablicy, w której zostaną zapisane liczby
Bardzo przydane do wczytywania zapisów z plików na modach.
Większość zapisanych danych na modach to liczby całkowite i właśnie z tego powodu przekształciłem kod DarkGL'a.
Kolejną funkcją jest dobrze znana funkcja z php "implode".
Dosłownie przeciwieństwo "explode" bo łączy kilka napisów w jeden oddzielając je podanym znakiem
stock implode(const strings[][], const num_strings, const character, output[], len) { new oLen = 0; for(new i=0; i<num_strings; i++) { oLen += formatex(output[oLen], len-oLen, "%s", strings[i]); if(i<num_strings-1) oLen += formatex(output[oLen], len-oLen, "%c", character); } }strings - tablica z napisami do połączenia
num_strings - ilość podanych napisów
character - znak, który ma być pomiędzy napisami
output - napis wyjściowy (po połączeniu)
len - długość napisu wyjściowego
Do tego żeby było parzyście dorobiłem "implode_num", które działa odwrotnie do "explode_num"
stock implode_num(const numbers[], size, const character, output[], len) { new oLen = 0; for(new i=0; i<size; i++) { oLen += formatex(output[oLen], len-oLen, "%i", numbers[i]); if(i<size-1) oLen += formatex(output[oLen], len-oLen, "%c", character); } }numbers - tablica z liczbami całkowitymi do połączenia
size - wielkość tablicy
character - znak, który ma rozdzielać pojedyncze liczby
output - napis wyjściowy
len - długość napisu wyjściowego
Wyniki skryptu testującego funkcje:
Spoiler
Dołączam jeszcze skrypt na którym wykonywałem testy.