Está bem,
Eu sei tudo sobre array_pop()
, mas isso exclui o último elemento. Qual é a melhor maneira de obter o último elemento de uma matriz sem excluí-lo?
EDIT: Aqui está um bônus:
$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
ou mesmo
$array = array('a', 'b', 'c', 'd');
unset($array[2]);
echo $array[sizeof($array) - 1]; // Output: PHP Notice: Undefined offset: 2 in - on line 4
Respostas:
As muitas respostas neste tópico nos apresentam muitas opções diferentes. Para poder escolher entre eles, eu precisava entender seu comportamento e desempenho. Nesta resposta que eu vou compartilhar minhas descobertas com você, por referência à informação versões do PHP
5.6.38
,7.2.10
e7.3.0RC1
( espera 13 dezembro, 2018 ).As opções
<<option code>>
que testarei são:$x = array_values(array_slice($array, -1))[0];
( como sugerido por rolacja )$x = array_slice($array, -1)[0];
( como sugerido por Stoutie )$x = array_pop((array_slice($array, -1)));
( como sugerido por rolacja )$x = array_pop((array_slice($array, -1, 1)));
( como sugerido por Westy92 )$x = end($array); reset($array);
( como sugerido por Iznogood )$x = end((array_values($array)));
( como sugerido por TecBrat )$x = $array[count($array)-1];
( como sugerido por Mirko Pagliai )$keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
( como sugerido por thrau )$x = $array[] = array_pop($array);
( como sugerido pelo usuário2782001 )$x = $array[array_key_last($array)];
( como sugerido pelo clone de Quasimodo ; disponível pelo PHP 7.3)(funções mencionadas: array_key_last , array_keys , array_pop , array_slice , array_values , count , end , reset )
As entradas de teste
<<input code>>
para combinar com:$array = null;
$array = [];
$array = ["a","b","c",null];
$array = ["a","b","c","d"];
$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }
Para testar que irá usar o
5.6.38
,7.2.10
e7.3.0RC1
recipientes docker PHP como:Cada combinação dos
<<option code>>
s listados acima<<input code>>
será executada em todas as versões do PHP. Para cada execução de teste, o seguinte trecho de código é usado:Para cada execução, isso fará com que var_dump o último valor recuperado da entrada de teste e imprima a duração média de uma iteração em femtossegundos (0,000000000000001º de segundo).
Os resultados são os seguintes:
O acima mencionado F atal, W Arning e N Otice códigos traduzir como:
Com base nesta saída, tirei as seguintes conclusões:
$x = end((array_values($array)));
$keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
$x = end($array); reset($array);
$x = $array[count($array)-1];
$x = $array[] = array_pop($array);
$x = $array[array_key_last($array)];
(desde PHP 7.3)$x = $array[count($array)-1];
(devido ao uso decount
)$x = $array[] = array_pop($array);
(devido à atribuição de valor à perda da chave original)$x = end($array); reset($array);
$x = end((array_values($array)));
array_key_last
função parece não ter nenhuma das limitações mencionadas acima, com exceção de ainda ser um RC no momento da redação deste documento (portanto, use o RC ou aguarde o lançamento em dezembro de 2018):$x = $array[array_key_last($array)];
(desde PHP 7.3)Um pouco, dependendo do uso da matriz como pilha ou fila, você pode fazer variações na opção 9.
fonte
$array[array_key_last($array)];
para sua referência. E, por favor, me dê alguma notificação quando terminar. Gostaria de ver os resultados de desempenho em comparação.Tentar
Para redefini-lo (obrigado @hopeseekr):
Link para o manual
@ David Murdoch adicionou:
$myLastElement = end(array_values($yourArray));// and now you don't need to call reset().
Em E_STRICT, isso produz o avisoObrigado o_O Tync e a todos!
fonte
$myLastElement = end(array_values($yourArray));
e agora você não precisa ligarreset()
.end(array_values())
dará um E_STRICT: "Somente variáveis devem ser passadas por referência"end((array_values($yourArray)))
Curto e grosso.
Eu vim com a solução para remover a mensagem de erro e preservar a forma de uma linha e o desempenho eficiente:
- solução anterior
Nota: Os parênteses extras são necessários para evitar a
PHP Strict standards: Only variables should be passed by reference
.fonte
$array = array_slice($array, -1); $lastEl = array_pop($array);
Pessoalmente eu acho que isso é melhor (sem o 'bug' parser)array_size() > 1
2. Verifique se o array é realmente um array. Ainda mantenho a resposta de @Iznogood, pois aend()
função incorporada do PHP já faz todo o trabalho duro de uma maneira mais eficiente.O que há de errado
array_slice($array, -1)
? (Consulte o manual: http://us1.php.net/array_slice )array_slice()
retorna uma matriz. Provavelmente não é o que você está procurando. Você quer o elementofonte
array_slice($array, -1)[0]
para obter o elementoreset(array_slice($array, -1))
é uma outra abordagem (que não causa um erro searray_slice()
retorna nada "menor" do que uma matriz de elemento único)array_slice($array, -1)[0] = "";
Uma maneira de evitar erros de passagem por referência (por exemplo, "end (array_values ($ foo))") é usar call_user_func ou call_user_func_array:
fonte
end((array_values($yourArray)))
call_user_func
truque também não funciona no PHP 7. Eu acho que você está preso com a criação de uma variável temporária.Se você não se preocupa em modificar o ponteiro interno (suporta matrizes indexadas e associativas):
Se você deseja uma função de utilitário que não modifique o ponteiro interno (porque a matriz é passada por valor e a função opera em uma cópia dela):
Observe que o PHP produz cópias "on-the-fly", ou seja, apenas quando realmente necessário. O
end()
próprio modifica a matriz, portanto internamente é gerada uma cópia da matriz.Portanto, a alternativa a seguir é realmente mais rápida, pois internamente não copia a matriz, apenas cria uma fatia:
Esse "foreach / return" é um ajuste para obter eficientemente o primeiro (e aqui único) item.
Por fim, a alternativa mais rápida, mas apenas para matrizes indexadas:
Para o registro, aqui está outra resposta minha , para o primeiro elemento da matriz.
fonte
array_last
função. Na primeira, você declara que a$array
cópia é copiada e, na segunda, que não é copiada. Onde está a diferença / por que é copiada na primeira implementação e não na segunda?não testado: isso não funcionaria?
Como a matriz retornada por array_values é passageira, ninguém liga se o ponteiro é redefinido.
e se você precisar da chave, acho que você faria:
fonte
Preciso disso muitas vezes para lidar com pilhas, e sempre me surpreendo que não haja função nativa que o faça sem manipular a matriz ou seu ponteiro interno de alguma forma.
Então, eu normalmente carrego uma função util que também é segura para uso em matrizes associativas.
fonte
Para obter o último elemento de uma matriz, use:
Referência
Eu iterei 1.000 vezes, capturando o último elemento de matrizes pequenas e grandes que continham 100 e 50.000 elementos, respectivamente.
Eu usei a versão 5.5.32 do PHP.
fonte
end () fornecerá o último elemento de uma matriz
fonte
A partir do PHP versão 7.3 as funções
array_key_first
earray_key_last
foi introduzido.Como matrizes no PHP não são tipos de matriz estritos, ou seja, coleções de tamanho fixo de campos de tamanho fixo iniciando no índice 0, mas matriz associativa estendida dinamicamente, o manuseio de posições com chaves desconhecidas é difícil e as soluções alternativas não funcionam muito bem. Por outro lado, matrizes reais seriam endereçadas internamente por aritmética de ponteiros muito rapidamente e o último índice já é conhecido em declaração por tempo de compilação.
Pelo menos o problema com a primeira e a última posição é resolvido pelas funções internas agora desde a versão 7.3. Isso funciona mesmo sem nenhum aviso em literais de matriz fora da caixa:
Obviamente, o último valor é:
fonte
Nenhuma modificação é feita nos ponteiros $ array. Isso evita a
o que pode não ser desejado em determinadas condições.
fonte
Para mim:
Com associados:
fonte
As principais respostas são ótimas, mas como mencionado por @ paul-van-leeuwen e @ quasimodos-clone, o PHP 7.3 apresentará duas novas funções para resolver esse problema diretamente - array_key_first () e array_key_last () .
Você pode começar a usar essa sintaxe hoje mesmo com as seguintes funções de polyfill (ou shim).
Advertência: Isso requer PHP 5.4 ou superior.
fonte
Para fazer isso e evitar o E_STRICT e não mexer com o ponteiro interno da matriz, você pode usar:
O elemento só funciona com uma cópia, para que não afete o ponteiro da matriz.
fonte
Outra solução:
fonte
Mais uma solução possível ...
fonte
E se:
$array == []
(retornafalse
)fonte
Você obterá o último elemento de uma matriz facilmente usando a lógica abaixo
Não apenas o último elemento, mas você também pode obter o penúltimo, o penúltimo e assim por diante, usando a lógica abaixo.
para o segundo último elemento, você deve passar apenas o número 2 na instrução acima, por exemplo:
echo ($ array [count ($ array) -2]);
fonte
Para obter o último valor da matriz:
Para remover a última matriz de formulários de valor:
fonte
array_slice($arr,-1,1)
resultará em outra matriz com o comprimento 1, não o último elemento$a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1));
Resultado:Array ( [0] => brown )
Simplesmente:
$last_element = end((array_values($array)))
Não redefine a matriz e não fornece avisos STRICT.
PS. Como a resposta mais votada ainda não possui parênteses duplos, enviei essa resposta.
fonte
Penso que esta é uma ligeira melhoria em todas as respostas existentes:
end()
ou soluções usandoarray_keys()
, especialmente com matrizes grandesfonte
array_values
na fatia de elemento único)Use a função end ().
fonte
Hoje em dia, eu preferiria sempre ter esse ajudante, como sugerido na resposta php.net/end .
Isso sempre mantém o ponteiro como está e nunca teremos que nos preocupar com parênteses, padrões rígidos ou o que for.
fonte
Nota: Para (PHP 7> = 7.3.0) , podemos usar array_key_last - Obtém a última chave de uma matriz
Ref: http://php.net/manual/en/function.array-key-last.php
fonte
E se você quiser obter o último elemento da matriz dentro do loop dela?
O código abaixo resultará em um loop infinito:
A solução é obviamente simples para matrizes não associativas:
fonte
fonte
A partir do PHP 7.3,
array_key_last
está disponívelfonte
Muito simples
fonte
$a = array(); $a[2] = 'c'; $a[1] = 'b'; echo end($a);
, retornaráb
minha solução simples, bonita e fácil de entender.
fonte