Portal SAMP
[Ajuda] foreach e y_iterate - Versão de Impressão

+- Portal SAMP (https://portalsamp.com)
+-- Fórum: SA-MP (https://portalsamp.com/forumdisplay.php?fid=5)
+--- Fórum: Área de suporte (https://portalsamp.com/forumdisplay.php?fid=6)
+--- Tópico: [Ajuda] foreach e y_iterate (/showthread.php?tid=4056)



foreach e y_iterate - Klaba - 10/10/2023

Sou um novato no mundo da programação, estou apreendendo aos poucos as funções e me deparei com o tal do foreach e do iterator.
Eu sei que não são nativos da linguagem pawn, foram desenvolvidos pela comunidade, mas eu queria saber sobre eles.

O que é um Foreach, quais seus parâmetros para ser usado, e por que usa-lo.
O que é um Iterator, quais seus parâmetros para ser usado, e por que usa-lo.

Desde já, obrigado!


RE: foreach e y_iterate - leonardos08bt - 10/10/2023

O y_iterate é a versão mais avançada do foreach, dentre as includes disponíveis do foreach a mais recomendada é a y_iterate.inc da biblioteca YSI.

Bom, o foreach ("for - each | para - cada") é um otimizador de loop, eu particularmente digo que o foreach é o calmante da CPU.

Você deve usar o foreach porque além dele otimizar seu servidor ele é mais simples de ser usado.

O foreach na maioria dos casos ganha de 10x0 do loop normal do pawn (for)

Uso do Foreach:

Citar:foreach(new int : lista) //Cria a variável int que vai ser repetida em cada 'ocupação' da lista

Diferença entre o loop normal (for) e o foreach 

Citar://Sem o foreach:
for(new i; i < MAX_PLAYERS; i++) //Loop de 0 à 1000(Número padrão do MAX_PLAYERS).
{
    if(IsPlayerConnected(i))
    {
        SendClientMessage(i, -1, "Você está conectado);
    }
}

------

//Com o foreach:
foreach(new i : Player) //Loop nos jogadores online!
{
    //Não necessita de IsPlayerConnected, pois o loop é feito apenas nos jogadores conectados.
    SendClientMessage(i, -1, "Você está conectado);
}

Viu a diferença e a simplicidade?
Com o loop normal, o loop vai ser repetido 1000 vezes mesmo se não possuir jogador conectado.
Com o foreach, o loop vai ser repetido apenas nos jogadores conectados. Muito melhor

Criar Lista
Citar:new Iterator:Vehicle<MAX_VEHICLES> //Nova iteração, Vehicle = nome da lista, MAX_VEHICLES = número máximo que a lista pode receber (recebe se for menor que o número máximo que definir)
Com isso eu crio uma lista chamada Vehicles.

Eu posso usar isso no foreach como mencionei anteriormente:
Citar:foreach(new veh : Vehicle)

Ah, como eu faço para adicionar algo nessa 'lista'? 
Citar:Iter_Add(lista, valor(variável));

Ex.:
new veh1 = CreateVehicle(411, ...);
new veh2 = CreateVehicle(411, ...);

Iter_Add(Vehicle, veh1);
Iter_Add(Vehicle, veh2);

e para remover?
Citar:Iter_Remove(lista, valor(variável));

Ex.:
Iter_Remove(Vehicle, veh2);

como pegar todos os jogadores online ou algo do tipo?
Citar:Iter_Count(lista);

Ex.:
printf("Jogadores Online: %d!", Iter_Count(Player));


Espero que tenha entendido, se eu deixei de informar algo, mande uma nova mensagem no tópico para eu ou outro membro responder a dúvida.


RE: foreach e y_iterate - Klaba - 10/10/2023

(10/10/2023 21:28)leonardos08bt Escreveu: O y_iterate é a versão mais avançada do foreach, dentre as includes disponíveis do foreach a mais recomendada é a y_iterate.inc da biblioteca YSI...

Ok, entendi que ele é um loop otimizado, mas eu não entendo o funcionamento dele, em si...

Ele é uma lista? É isso? Uma lista que eu adiciono ou removo itens? E uso um foreach para percorrer todos os itens da lista na relação em que:

Código:
foreach(new i : Player)
 
A variável i assumiria todos os valores da lista Player?

Supomos que a lista Player tenha 5 itens na lista, a variável i assumiria 1, 2, 3, 4 e 5? Em cada execução?


RE: foreach e y_iterate - leonardos08bt - 10/10/2023

O foreach procura valores dentro de listas.
Sim, a variável i assumiria (não de uma só vez), é parecido com o loop normal.
for(new i; i < 10; *i++*). Se i for menor que 10 ele acrescenta +1.
No foreach também, mas apenas se houver algum valor armazenado na lista.
Ele funciona para otimizar loop's da seguinte forma:

Exemplo:

Código:
new Iterator:lista<10> //Lista com 10 'vagas'

public OnPlayerConnect(playerid)
{

    Iter_Add(lista, playerid); //Adiciona na lista o id do jogador
    return 1;
}



public OnPlayerDisconnect(playerid)
{

    Iter_Remove(lista, playerid); //Remove da lista o id do jogador
    return 1;
}



//Exemplo usando zcmd
CMD:players(playerid, params[])
{

    new str[64];
    foreach(new i : lista) //Procura todos os jogadores da lista
    {
        new Nome[MAX_PLAYER_NAME]; GetPlayerName(playerid, Nome, sizeof(Nome));

        format(str, sizeof(str), "%s[%d]", Nome, i);
        SendClientMessage(playerid, -1, str);
    }
    return 1;
}

A variável i funciona quase da mesma forma que se eu criasse no loop normal, mas, ele pega da vaga o valor dela, se na vaga 1 tiver o valor 3, o i vai ser 3. Se na vaga 2 estiver o valor 1, o i vai ser 1, acho que dá pra compreender.


RE: foreach e y_iterate - PT_Player - 10/10/2023

Te deixo toda a documentacao sobre o mesmo.

https://github.com/pawn-lang/YSI-Includes/blob/5.x/YSI_Data/y_iterate.md

se precisas de ajuda so avisar


RE: foreach e y_iterate - Device-Black - 13/10/2023

No Open:MP tem uma função chamada GetPlayers, acredito que ela deve ser mais rapida em relação a loops com jogadores:
Código PHP:
new Players[MAX_PLAYERS];

public 
OnPlayerConnect(playerid) {
    
GetPlayers(Players);
    return 
1;
}

public 
OnPlayerDisconnect(playeridreason) {
    
GetPlayers(Players);
    return 
1;
}

KillAllPlayers() {
    static 
i;
    for(
0MAX_PLAYERSi++) {
        if(
Players[i] == INVALID_PLAYER_ID) break;
        
SetPlayerHealth(Players[i], 0.0);
    }


Mas foreach continua sendo útil, tendo em vista que voce pode criar outras listas como Admin contendo só jogadores da staff, Vip contendo apenas jogadores vip obviamente e etc
Realmente foreach foi uma include de grande ajuda para todos os programadores experiente...