←  Gotowe funkcje

AMXX.pl: Support AMX Mod X i SourceMod

»

Funkcje przyspieszające pracę na tablicach

  • +
  • -
AwIlL^^ - zdjęcie AwIlL^^ 11.12.2017

Chciałbym przedstawić kilka ciekawych funkcji, które potrafią ułatwiać życie.

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.

Załączone pliki

Odpowiedz

  • +
  • -
DarkGL - zdjęcie DarkGL 13.12.2017

4 lata po opublikowaniu ktoś ulepszył propsy !

Odpowiedz