Como obter a última chave em uma matriz?


Respostas:


610

Uma solução seria usar uma combinação de ende (citação) :key

  • end() avança o ponteiro interno da matriz para o último elemento e retorna seu valor.
  • key() retorna o elemento de índice da posição atual da matriz.

Portanto, uma parte do código como esta deve fazer o truque:

$array = array(
    'first' => 123,
    'second' => 456,
    'last' => 789, 
);

end($array);         // move the internal pointer to the end of the array
$key = key($array);  // fetches the key of the element pointed to by the internal pointer

var_dump($key);

Saída:

string 'last' (length=4)

ou seja, a chave do último elemento da minha matriz.

Depois que isso for feito, o ponteiro interno da matriz estará no final da matriz. Conforme indicado nos comentários, você pode executar reset()na matriz para trazer o ponteiro de volta ao início da matriz.


17
@Pim: depende do que o OP quer fazer com esse array depois (pode não ser necessário chamar reset()) ;; mas você está certo ao apontar essa função, o que pode ser útil.
Pascal MARTIN

3
@PascalMARTIN +1 Acho que adicionar um comentário sobre o reset () na sua resposta será muito útil.
Lulu

Essa abordagem não funciona se a matriz tiver valores duplicados. por exemplo. pois array('a', 'b', 'c', 'd', 'a')ele retornará a chave 0 em vez de 4. #
1212 Marc Marc

2
@ Marc esta abordagem funciona corretamente, mesmo se houver valor duplicado.
9166 Jeff

11
@pppp ele não funciona porque ... cheque o retorno final () e, em seguida, pense novamente;)
forsberg

79

Embora end()pareça ser o mais fácil, não é o mais rápido. A alternativa mais rápida e muito mais forte é array_slice():

$lastKey = key(array_slice($array, -1, 1, true));

Como dizem os testes , em um array com 500000 elementos, é quase 7x mais rápido!


98
animado com esta resposta, fiz um teste rápido de 100.000 iterações, comparando (a) end($arr);$key = key($arr);reset($arr);com (b) $key = key(array_slice($arr,-1,1,true));... o que resultou em end()ser MUITO mais rápido! end () = 0,05326 segundos, array_slice = 8,506 segundos ... hein?
Neokio 26/09/12

54
As funções embutidas do PHP foram criadas por nerds extremos. Não tente recriar essas funções. As chances são de que você faça algo muito mais lento que o original. A menos que você seja algum tipo de mago do mal, é claro.
dmmd

16
end()é mais rápido porque pode ser derivado de uma função C muito simples, como:int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }
Gustav

10
@Gustav Acredito que a implementação C subjacente do PHP, na verdade, tenha um ponteiro interno lastpara o último elemento. Fazendo end()praticamente O (1). :-)
Eric

15
@ dmmd, tenho certeza que a equipe do PHP ficaria extremamente satisfeita por serem chamados de nerds.
Datasn.io

53

eu prefiro

end(array_keys($myarr))

19
provoca AVISO RESTRITA final espera uma referência variável
Wiliam

25
Você pode usar end((array_keys($myarr)))para contornar o aviso.
Ben Fortune

9
@BenFortune Isso foi corrigido no PHP7: "No PHP 5, o uso de parênteses redundantes em torno de um parâmetro de função pode acalmar avisos rígidos de padrões quando o parâmetro de função for passado por referência. O aviso agora será sempre emitido."
Dominic Scheirlinck 18/01/16

isso é um aviso totalmente desnecessário! é uma coisa normal e usual em todas as outras línguas!
Azerafati

11
Em outros idiomas, as funções não operam em ponteiros, funcionam?
jurchiks

52

Desde o PHP 7.3 (2018), existe (finalmente) a função para isso: http://php.net/manual/en/function.array-key-last.php

$array = ['apple'=>10,'grape'=>15,'orange'=>20];
echo array_key_last ( $array )

irá produzir

orange

4
Horray! Eu estava prestes a adicionar esta resposta. Você poderia destacar a versão "PHP 7.3" e o ano de 2018? Será mais fácil de detectar esta notícia impressionante para os outros
Tomáš Votruba

Também é bom mencionar que isso NÃO afeta o ponteiro interno da matriz.
mvorisek

30

Apenas use : echo $array[count($array) - 1];


75
Isso funciona apenas se você tiver matrizes numéricas. Falha com matrizes associadas.
Jeremy J Starcher

12
Isso não apenas funciona em matrizes numéricas, mas também mostra a chave, mas mostra o valor, não é?
Nanne 22/10

Eu também, Jake, podemos fazer algo em que dividimos esse hit top do Google (numero e associativo), para que tenhamos uma referência antiga para ambos ... Eu só descobri que era para assoc após a análise, o int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }que é interessante, mas não é bom para o negócio quando você estiver em um orçamento tempo
lol

5
Além disso, mesmo para uma matriz numérica, lembre-se de que as matrizes numéricas não precisam estar em ordem ou usar todos os números. Isso funcionará se você não atribuir explicitamente valores numéricos, mas se fizer $a[1] = 1; $a[5] = 5; $a[0] = 0;isso, terá uma matriz com as chaves (1, 5, 0), nessa ordem. count($a)produzirá 3 e $a[2]não está definido. Certamente não lhe devolve 5.
Daniel Skarbek

11
Leia a pergunta novamente "Como obter a última chave em uma matriz?"

20

Não sei se isso será mais rápido ou não, mas parece mais fácil fazê-lo dessa maneira, e você evita o erro ao não passar uma função para end () ...

ele só precisava de uma variável ... não é grande coisa para escrever mais uma linha de código e, se necessário, desmarque-a.

$array = array(
    'first' => 123,
    'second' => 456,
    'last' => 789, 
);

$keys = array_keys($array);
$last = end($keys);

2
Essa resposta (embora tecnicamente correta) é um desperdício / ineficiente porque requer a criação de uma matriz adicional (de comprimento igual ao original). Isso significa que o desperdício aumenta conforme a matriz original. Isso nunca deve ser escolhido sobre a resposta eficiente de Pascal MARTIN. Estou surpreso que isso tenha muitos votos positivos.
Mckmackusa 19/04

12

A partir do PHP7.3, você pode acessar diretamente a última chave (no nível externo) de uma matriz com array_key_last ()

Definitivamente coloca grande parte do debate nesta página na cama. É sem dúvida o melhor desempenho, não sofre efeitos colaterais e é uma técnica direta, intuitiva e de chamada única para fornecer exatamente o que essa pergunta busca.

Uma referência aproximada como prova: https://3v4l.org/hO1Yf

array_slice() + key():  1.4
end() + key():         13.7
array_key_last():       0.00015

* A matriz de teste contém 500000 elementos, microtime repetido 100x, em seguida, calculada a média e multiplicada por 1000 para evitar notação científica. Crédito para @MAChitgarha por avaliação inicial comentada na resposta de @ TadejMagajna .

Isso significa que você pode recuperar o valor da chave final sem:

  1. movendo o ponteiro da matriz (que requer duas linhas de código) ou
  2. classificação, reversão, popping, contagem, indexação de uma matriz de chaves ou qualquer outro tipo de tolice

Essa função estava muito atrasada e uma adição bem-vinda ao cinto de ferramentas da função de matriz que melhora o desempenho, evita efeitos colaterais indesejados e permite código limpo / direto / intuitivo.

Aqui está uma demonstração :

$array = ["a" => "one", "b" => "two", "c" => "three"];
if (!function_exists('array_key_last')) {
    echo "please upgrade to php7.3";
} else {
    echo "First Key: " , key($array) , "\n";
    echo "Last Key: " , array_key_last($array) , "\n";
    next($array);                 // move array pointer to second element
    echo "Second Key: " , key($array) , "\n";
    echo "Still Last Key: " , array_key_last($array);
}

Resultado:

First Key: a
Last Key: c     // <-- unaffected by the pointer position, NICE!
Second Key: b
Last Key: c     // <-- unaffected by the pointer position, NICE!

Algumas notas:

  • array_key_last()é a função irmão de array_key_first () .
  • Ambas as funções são "ignorantes em relação aos ponteiros".
  • Ambas as funções retornam null se a matriz estiver vazia.
  • As funções descartadas dos irmãos ( array_value_first()& array_value_last()) também teriam oferecido acesso ignorante aos elementos de suporte de livros, mas evidentemente não conseguiram obter votos suficientes para ganhar vida.

Aqui estão algumas páginas relevantes que discutem os novos recursos:

ps Se alguém estiver avaliando algumas das outras técnicas, você pode consultar esta pequena coleção de comparações: ( Demo )

Duration of array_slice() + key():     0.35353660583496
Duration of end() + key():             6.7495584487915
Duration of array_key_last():          0.00025749206542969
Duration of array_keys() + end():      7.6123380661011
Duration of array_reverse() + key():   6.7875385284424
Duration of array_slice() + foreach(): 0.28870105743408

2
Esta resposta deve estar no topo da lista. É simplesmente completo.
John

11
Uau, um DV nesta resposta minha? Qual era o problema, muito abrangente / definitivo / explicativo / apoiado? Pfft. Definitivamente continue a empurrar mensagens que se atrevem a informar. Bom trabalho. Caso você não saiba, o botão DV é para posts "não úteis". Por favor, pergunte-se qual é o seu objetivo aqui.
mickmackusa 18/04

8

Tente usar array_pop e array_keys funcionar da seguinte forma:

<?php

$array = array(
    'one' => 1,
    'two' => 2,
    'three' => 3
);

echo array_pop(array_keys($array)); // prints three

?>

14
Isso é muito lento se sua matriz tiver mais de uma coisa. Por favor, não faça isso.
Andrey

3
e provoca AVISO RIGOROSA também, referência variável
Wiliam

array_pop () diminuiria a matriz original (removendo o último elemento). Não tenho certeza se isso importa ou não para o OP, mas certamente será importante para os outros.
Programster

11
Na verdade não. Neste exemplo, array_pop()opera com o valor de retorno array_keys()e não na matriz original.
Petko Bossakov 23/01/19

Como existem outras respostas mais eficientes que não acionam um AVISO, estou votando negativamente nesta resposta.
Mckmackusa 19/04

6

A partir do PHP> = 7.3 array_key_last()é a melhor maneira de obter a última chave de qualquer array. Usando combinação de end(), key()e reset()apenas para obter última chave de uma matriz é ultrajante.

$array = array("one" => bird, "two" => "fish", 3 => "elephant");
$key = array_key_last($array);
var_dump($key) //output 3

compare isso com

end($array)
$key = key($array)
var_dump($key) //output 3
reset($array)

Você deve redefinir a matriz para que o ponteiro fique no início se estiver usando a combinação de end()ekey()


4

Eu também gostaria de oferecer uma solução alternativa para esse problema.

Supondo que todas as suas chaves sejam numéricas sem intervalos, meu método preferido é contar a matriz e menos 1 a partir desse valor (para explicar o fato de que as chaves da matriz começam em 0.

$array = array(0=>'dog', 1=>'cat');

$lastKey = count($array)-1;
$lastKeyValue = $array[$lastKey];

var_dump($lastKey);
print_r($lastKeyValue);

Isso lhe daria:

int (1) cat


11
Isso não funcionará para matrizes onde as chaves não são incrementais, por exemplo, matriz (0 => 'cachorro', 5 => 'gato'); $ LASTKEY retornaria um valor errado
Kakoma

@kakoma - Como diz o meu post "Assumindo que todas as suas chaves são numéricas sem lacunas".

Para quem quer saber, use "array_values" do PHP para redigitar a matriz para sequencial numérico. php.net/manual/en/function.array-values.php

11
Como esta resposta lida apenas com uma fração das possibilidades da matriz (matrizes numéricas consecutivas e com chave), essa resposta não oferece uma resposta robusta / correta à pergunta generalizada do OP. Voto negativo.
Mckmackusa 19/04

4

Você pode usar isto:

$array = array("one" => "apple", "two" => "orange", "three" => "pear");
end($array); 
echo key($array);

Outra solução é criar uma função e usá-la:

function endKey($array){
end($array);
return key($array);
}

$array = array("one" => "apple", "two" => "orange", "three" => "pear");
echo endKey($array);

11
Esta resposta não fornece nada de novo que ainda não esteja neste segmento.
Martin

11
Martin, ninguém usa função para obter o resultado.
Atif Tariq

11
você precisa adicionar 1 linha de código em uma função? Essa é uma interface desnecessária.
Martin

11
Martin, qual linha.
Atif Tariq

2
a linha em sua função
Martin

3
$arr = array('key1'=>'value1','key2'=>'value2','key3'=>'value3');
list($last_key) = each(array_reverse($arr));
print $last_key;
// key3

2
Inverter a matriz inteira apenas para obter um valor é certamente menos eficiente que o método de PascalMARTIN. Mesmo tecnicamente correto, nunca deve ser usado no lugar da abordagem de Pascal.
Mkmackusa #

3

Eu apenas peguei a função auxiliar de Xander e a aprimorei com as respostas anteriores:

function last($array){
  $keys = array_keys($array);
  return end($keys);
}


$arr = array("one" => "apple", "two" => "orange", "three" => "pear");    
echo last($arr);
echo $arr(last($arr));

1

Tente este com array_reverse().

 $arr = array(
     'first' => 01,
     'second' => 10,
     'third' => 20, 
 );  
 $key = key(array_reverse($arr));
 var_dump($key);

1

É estranho, mas por que este tópico não é ter esta resposta:

$lastKey = array_keys($array)[count($array)-1];


0
$array = array(
    'something' => array(1,2,3),
    'somethingelse' => array(1,2,3,4)
);

$last_value = end($array);
$last_key = key($array); // 'somethingelse'

Isso funciona porque o PHP move seu ponteiro de matriz internamente por $ array


2
Esta é uma duplicata do método de PascalMARTIN. Por favor, poupe esta página e exclua sua resposta tardia / duplicada. Votado.
Mckmackusa

0

A melhor solução possível que também pode ser usada é usada em linha:

end($arr) && false ?: key($arr)

Esta solução é apenas expressão / declaração e fornece bom não é o melhor desempenho possível.

Exemplo de uso embutido:

$obj->setValue(
    end($arr) && false ?: key($arr) // last $arr key
);


ATUALIZAÇÃO: No PHP 7.3+: use (é claro) o array_key_last()método recém-adicionado .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.