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ć rozdzielonycharacter - 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łączenianum_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łączeniasize - 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.


Dodatki SourceMod






test_funkcji.amxx








