PHP Array Usando RESET para Extrair a Primeira Linha de um Array

$y[0] = [ 'col1' => 'A', 'col2' => 'B', 'col3' => 'C' ];
$y[1] = [ 'col1' => 'value1', 'col2' => 'value2', 'col3' => 'value3' ];
$y[2] = [ 'col1' => 'value4', 'col2' => 'value5', 'col3' => 'value6' ];
$y[3] = [ 'col1' => 'value7', 'col2' => 'value8', 'col3' => 'value9' ];

$header = reset($y);
var_dump($header);

// array(3) { 
//   ["col1"] => string(1) "A"
//   ["col2"] => string(1) "B"
//   ["col3"] => string(1) "C"
// }

Pode parecer uma tarefa super simples pegar o primeiro elemento de um array, e realmente é!!! Desde a semana passada o reset() é o meu jeito preferido de fazer isso.

Recentemente quando estive implementando a importação de um arquivo tipo planilha de dados naturalmente tive a necessidade de processar a primeira linha a qual continha o HEADER dos dados. Então me deparei com um código existente que me pareceu muito estranho a princípio, dá uma olhada nisso…

$mapped_headers = $this->map_headers(reset($spreadsheet_rows));

Para quem é familiar a este tipo de processamento sabe que estamos falando de um array bidimensional no melhor estilo linhas x colunas. O que eu não entendi foi aquele reset() ali na invocação do map_headers… que janho!!!

Como de praxe fui debugar e entender como a combinação funcionava… Para o meu espanto, somente agora eu entendi que o comando reset, além de resetar o ponteiro interno do array, retorna também o primeiro elemento do array.

Isto é fantástico!!! Eu sempre me perguntei por que o PHP não tinha um comando first() para pegar o primeiro elemento de um array já que temos o comando current() e o comando end().

Uma alternativa ao reset() seria inverter a array e usar o comando end(), mas acho que não tem necessidade de complicar o código com essa miscelânea pra atingir o mesmo resultado.

$r = array_reverse($y);
$header = end($r);
var_dump($header); 

// array(3) { 
//   ["col1"] => string(1) "A"
//   ["col2"] => string(1) "B"
//   ["col3"] => string(1) "C"
// }

Outra combinação possível seria combinar current() com reset(), mas também seria um desperdício já que o reset já faz o trabalho esperado.

reset($y);
$header = current($y);
var_dump($header); 

// array(3) { 
//   ["col1"] => string(1) "A"
//   ["col2"] => string(1) "B"
//   ["col3"] => string(1) "C"
// }

Outra alternativa segura de pegarmos o primeiro elemento da array seria fatiar o array com array_slice(), lembrando que este comando extrai o elemento como bidimensional preservando o índice da linha. Ainda assim teria que combinar com array_shift() ou array_pop() para pegar o primeiro elemento como array simples.

$first_row = array_slice($y, 0, 1);
var_dump($first_row); 

// array(1) {
//   [0]=>
//   array(3) {
//     ["col1"]=> string(1) "A"
//     ["col2"]=> string(1) "B"
//     ["col3"]=> string(1) "C"
//   }
// }

$header = array_shift($first_row);
var_dump($header); 

// array(3) { 
//   ["col1"] => string(1) "A"
//   ["col2"] => string(1) "B"
//   ["col3"] => string(1) "C"
// }

Pra finalizar uma última alternativa segura que podemos considerar seria utilizar array_values(). Sabemos que a primeira linha do array representam os headers não importa qual é a chave utilizada na indexação destas linhas. Então array_values() garante que o índice da primeira linha seja ZERO através do re-sequenciamento do array sem alterar a ordem de seus elementos.

$y['Z'] = [ 'col1' => 'A', 'col2' => 'B', 'col3' => 'C' ];
$y['X'] = [ 'col1' => 'value1', 'col2' => 'value2', 'col3' => 'value3' ];
$y['S'] = [ 'col1' => 'value4', 'col2' => 'value5', 'col3' => 'value6' ];
$y['J'] = [ 'col1' => 'value7', 'col2' => 'value8', 'col3' => 'value9' ];

$header = array_values($y)[0];
var_dump($header); 

// array(3) { 
//   ["col1"] => string(1) "A"
//   ["col2"] => string(1) "B"
//   ["col3"] => string(1) "C"
// }

Não exploramos outras alternativas como loop foreach() e for() mas nem precisa, com o PHP certamente encontraremos pelo menos mais meia dúzia de outras formas para atingir o mesmo resultado.

Agora convenhamos, o reset() arrasou!