Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Rodolfo TI

Pegar valor ultima posição de um array

Recommended Posts

Olá amigos uso um sistema que funciona a partir do jpgraph para gerar gráficos dinamicos, porém preciso usar o ultimo valor de uma array para definir uma legenda, tentei com end , com count -1 entre outras coisas , será que meu array está com problemas ? como debuga-lo? Algumas vezes ele retonar zero.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Só há um problema com o uso de array pop. Além dele retornar o último valor do array, ele remove-o. Logo você não possuirá mais o mesmo valor no array.

O mais prático é o uso de ponteiros. Um array não é nada mais que uma estrutura de dados (que pode ser do tipo lista ou árvore).

Poucos desenvolvedores de PHP sabem utilizar ponteiros. Um ponteiro, por default, está apontado para a primeira posição de um array.

A função current retorna o valor aonde o ponteiro se encontra, já a função end. coloca o ponteiro na última posição do array. Veja no exemplo:

//cria-se o array
$array = array('primeiro item' , 'segundo item' , 'terceiro item');

//imprime-se o valor do array na posição atual do ponteiro
var_dump(current($array));

//envia-se o ponteiro para o final do array
end($array);

//imprime-se o valor do array na posição atual do ponteiro
var_dump(current($array));

Saída:

 

string(13) "primeiro item"
string(13) "terceiro item"

Ponteiros são muito úteis nesses casos, mas pouca gente utiliza-os.

Compartilhar este post


Link para o post
Compartilhar em outros sites

já a função end. coloca o ponteiro na última posição do array.

Além de colocar o ponteiro no final do array, a função [inline]end()[/inline] também retorna o elemento:

 

<?php
$items = [10, 20, 30, 40, 50]; //5.4+

echo end($items); //50

 

:seta: http://php.net/manual/en/function.end.php

Compartilhar este post


Link para o post
Compartilhar em outros sites

já a função end. coloca o ponteiro na última posição do array.

 

Aproveitando a pergunta, queria tirar uma dúvida sobre esse assunto.

 

Então se eu fizer dessa forma, funcionaria?

$ultimo = end(array('primeiro item' , 'segundo item' , 'terceiro item'));

 

Meu exemplo não é funcional, só pra exemplificar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não irá funcionar, pois o parâmetro de end será passado como referência. Somente variáveis podem ser passadas por referência.

Se tentar executar, terá o seguinte fatal error:

 

 

Fatal error: Only variables can be passed by reference

 

 

Para funcionar, deverá, ao menos, fazer assim:

 


$array = ['primeiro item' , 'segundo item' , 'terceiro item']; $ultimo = end($array);

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi, mais porque então assim funciona:

 

<?php

$string = "nomeArquivo.pdf";
$extensao = end(explode('.', $string));

/*-*/
var_dump($extensao);

?>

 

Não seria por referência também?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Até onde eu sei, o retorno de funções pode podiam ser passados como referência, mas isso gerará um Strict Standards. Veja:

$string = "nomeArquivo.pdf";
$extensao = end(explode('.', $string));

Saída:

Strict Standards: Only variables should be passed by reference

 

Código em funcionamento:

http://codepad.viper-7.com/Lw5a8i

 

Um Strict Standard é um tipo diferente de erro. Não é um erro, é um aviso que indica a compatibilidade com futuras versões do PHP, ele serve para "antecipar" possíveis mudanças, pelo menos é o que eu entendo dele. Assim como um Notice, o Strict Standard pode ser suprimido, o que indica seu código estar funcionando.

 

Edit--

É no passado, alterei lá em cima.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado pela resposta @Gabriel Heming,

 

Aqui realmente não exibe essa mensagem.

Eu usava sem descriminação esse pequeno código para capturar extensão de arquivos no upload, vou rever e alterar para não dar problema no futuro.

 

Ótima explicação, só não positivo seu post porque atingi o limite :( Cruel

Compartilhar este post


Link para o post
Compartilhar em outros sites

Essa forma funciona mas ela dispara um Strict Standards para te avisar de que a forma como está trabalhando é errada ou está depreciada.

 

O que pode estar havendo é que você não está definindo um error_reporting() alto o suficiente para ancançar o valor dessa constante (2048) e/ou não a está incluindo na referida definição.

 

E E_STRICT, segundo o manual existe desde o PHP 5, mas só faz parte de E_ALL a partir do 5.4.

 

Sendo assim, caimos na velha estória de, durante o desenvolvimento, iniciar o script com:

ini_set( 'display_errors', TRUE );

error_reporting( E_ALL | E_STRICT ); // PHP > 5 e < 5.4

error_reporting( E_ALL ); // PHP 5.4+
Quanto a questão de pegar o último valor, em algumas circunstâncias, usar end() não é a melhor pedida pois, caso o mesmo array seja reutilizado em sequencia para um loop por exemplo, ele pode não mostrar todos elementos pois seu ponteiro está no final do mesmo:
<?php

$array = range( 'a', 'z' );

var_dump( $array, end( $array ) );

while( list( $k, $v ) = each( $array ) ) {

    var_dump( $v );
}
Você verá a depuração do intervalo e a letra z duas vezes pois o loop while, diferente do for e do foreach, não resetam o ponteiro do array, manual e automaticamente (respectivamente), coisa que você precisaria fazer manualmente adicionando um:

reset( $array );
Antes do [inline]while[/inline]

 

Nesses casos você pode usar:

var_dump( $array[ ( count( $array ) - 1 ) ] );
Que tudo continua bem.

 

Caso o array seja associativo, óbvio, isso não funcionaria, mas também há uma alternativa:

var_dump( array_slice( $array, ( count( $array ) - 1 ), ( count( $array ) - 1 ) ) );
Lógico e evidente que o count(0 deveria ser armazenado numa variável para não ser invocado duas vezes.

 

E o bom dessa abordagem é que ela funciona mesmo que o array de entrada seja misto de entradas associativas e indexadas, tal qual end(), porém se o incoveniente de mexer com seus ponteiros.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Bruno Augusto, obrigado pela explicação!

 

Colocando [inline]error_reporting( E_ALL | E_STRICT );[/inline] no sistema aqui não só apareceu o erro do código que mencionei acima, como outros também. Vou providenciar e corrigir :D

 

Obrigado mais uma vez!

 

:joia:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal muito obrigado pelas respostas, todoas foram muito úteis, tentei alguns métodos porém sem sucesso

while($arrPPsr = mysql_fetch_array($qryPPsr)){
       $sr[] = $arrPPsr['qtd']/$auxQtdTot*100;
       $usr=$arrPPsr['qtd']/$auxQtdTot*100;// Pega somente o valor da ultima contagem
       $tsr=$arrPPsr['qtd']; // Recebe o ultimo total 
       $usr = number_format($usr,1, ".", "");
}

Essa é a estrutura de repetição que preenche meu array, usei a variavel tsr pra pegar o ultimo total e a usr pra pegar o ultimo valor da contagemd e porcentagem. Será esta a melhor forma de fazer ? Como disse utilizarei esses valores para um gráfico.

Não perco rendimento usando desta forma ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso depende, Rodolfo. Depende do que você realmente quer fazer.

Ao longo do tópico foram mostradas várias formas de se resolver o proposto. Cada alternativa tem seus prós e seus contras e alguns deles foram mostrados.

De um modo geral, a forma acima não tem problemas de performance graves. Mas existem micro-otimizações que você talvez pudesse fazer:

while( $arrPPsr = mysql_fetch_array( $qryPPsr ) ) {

    $math = $arrPPsr['qtd'] / $auxQtdTot * 100;

    $sr[] =& $math;
    
    //$tsr=$arrPPsr['qtd']; // Recebe o ultimo total 
    
    //$usr = number_format( $math, 1, ".", "" );
}

O que foi feito:

  • O cálculo matemático foi reaproveitado, ao invés de ser executado duas vezes.

    Até mesmo a adicção ao array foi reaproveitada por não criar o valor no array e sim referenciar ao valor de outra variável.
  • Não houve criação de duas variáveis que não seriam utilizadas, pelo menos não no exemplo apresentado.

    Como parece que $usr será utilizada, você pode descomentá-la. Já $tsr é desnecessária pois indica que você quer jogar o valor da última quantidade pra fora do laço.

    Mas ao terminar a iteração, o ponteiro do array já estará no final, logo acessar [inline]$arrPPsr['qtd'][/inline] resultará no mesmo que a criação dessa variável.

Mas, micro-otimizações não são coisas muito importantes no desenvolvimento de uma Aplicação pois podem atrasar a entrega da mesma.

Uma vez pronta, de repente num futura bugfix, você pode liberar uma versão já com essas otimizações.[

Compartilhar este post


Link para o post
Compartilhar em outros sites

Uma vez pronta, de repente num futura bugfix, você pode liberar uma versão já com essas otimizações.[

A forma que você mostrou é muito interessante ainda não tinha utilizado operador dessa forma, vou testar em minha aplicação, hoje meu foco é manutenção do código e aperfeiçoamento então essas micro-otimizações são ferramentas interessantes. Não sou expert em PHP e peguei uma tarefa díficil para meu nível de conhecimento, é um código complexo com uma lógica complexa. Pretendo fazer pequenos projetos para me aperfeiçoar e isso com certeza irá me ajudar a desenvolver códigos mais organizados ao se tratar de performance.

 

Meu objetivo com esse trecho do código é o seguinte, tenho uma legenda referente a um gráfico, que deve mostrar o total de "WE" (que são fichas) por exemplo e o percentual referente aquela ficha.

 


while($arrPPsr = mysql_fetch_array($qryPPsr)){
  $sr[] = $arrPPsr['qtd']/$auxQtdTot*100;
  $usr=$arrPPsr['qtd']/$auxQtdTot*100;// Pega a ultima coluna do gráfico e seu total de fixas, $arrPPsr['qtd'] é o total e usa a $auxQtdTot*100; para saber a porcentagem, isso referente somente a ultima coluna, por isso a duvida em pegar somente a ultima posição do array.
 

$tsr=$arrPPsr['qtd']; // Faz a mesma coisa que acima só que nesse caso pega só o total de fixas

$usr = number_format($usr,1, ".", ""); // formata o numero
}

melhorei o comentário pra ver se ajuda a entender minha dúvida, ainda não testei a dica do Bruno mas concerteza o farei.

 

Muito obrigado! Sou novo no fórum e estou adorando a equipe, vocês todos estão de parabéns!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.