Desestruturação de Matriz Simétrica no PHP 7.1

Desestruturação de Matriz Simétrica

Symmetric array destructuring (Desestruturação de Matriz Simétrica), a grosso modo nada mais é do que desmembrar e manipular um array e para isso o PHP conta com um recurso que se chama “list”. A função list(), que na verdade não se trata de uma função mas sim um construtor de linguagem, é utilizada para criar variáveis como se fossem arrays, caso não conheça esse recurso ou não lembre vou mostrar alguns exemplos.

list($a, $b, $c) = ['foo', 'bar', 'baz'];

echo $a; // "foo"
echo $b; // "bar"
echo $c; // "baz"

A ideia é bem simples, agora veja um caso onde é omitida a última variável.

list($a, $b) = ['foo', 'bar', 'baz'];

echo $a; // "foo"
echo $b; // "bar"

Como pode ver ele simplesmente não irá associar o último valor. Mas e se não passarmos um dos valores do array?

list($a, $b, $c) = ['foo', 'bar'];

echo $a; // "foo"
echo $b; // "bar"
echo $c; // Undefined offset: 1

Uma chamada Undefined offset será lançada na variável que sobrou.
Bem, agora veja um exemplo onde queremos saltar o índice 1 do array.

list($a, , $b) = ['foo', 'bar', 'baz'];

echo $a; // "foo"
echo $b; // "baz"

Bom, essa função é bem simples de se usar e no PHP 7.1 é possível especificar o índice do array que queremos desempacotar em uma matriz associativa.

$person = [
'name' => 'Sebastian',
'job' => 'Developer',
];

list('job' => $job) = $person;
echo $job; // "Developer"

Você também pode usar o recurso dentro de um loop. Como por exemplo um foreach.

$people = [
['name' => 'Freek', 'role' => 'Developer'],
['name' => 'Sebastian', 'role' => 'Developer'],
['name' => 'Willem', 'role' => 'Designer'],
];

$names = [];

foreach ($people as $person) {
list('name' => $names[]) = $person;
}

var_dump($names); // ["Freek", "Sebastian", "Willem"];

Também na versão 7.1 temos uma sintaxe alternativa para essa funcionalidade, que além ser mais concisa ela não se assemelha a uma chamada de função, evitando mal-entendidos de novos usuários.

// Antes do PHP 7.1
list($a, $b, $c) = ['foo', 'bar', 'baz'];

// Depois do PHP 7.1
[$a, $b, $c] = ['foo', 'bar', 'baz'];

Como você pode observar agora podemos passar no lugar de list apenas os símbolos [ ]. Caso você não tenha gostado dessa nova maneira de usar o list() você pode continuar usando da maneira tradicional, pois pelo menos até o PHP 7.1 o list ainda é suportado.
Abaixo está um exemplo um pouco mais elaborado do que é possível fazer este recurso.

$produce = [
[1, 'apple', 'fruit'],
[2, 'banana', 'fruit'],
[3, 'carrot', 'vegetable'],
];

$mappedProduce = [];

foreach ($produce as [$id, $name, $type]) {
$mappedProduce[] = [
'id' => $id,
'name' => $name,
'type' => $type,
];
}

print_r($mappedProduce);

// result
// Array
// (
// [0] => Array
// (
// [id] => 1
// [name] => apple
// [type] => fruit
// )
// [1] => Array
// (
// [id] => 2
// [name] => banana
// [type] => fruit
// )
// [2] => Array
// (
// [id] => 3
// [name] => carrot
// [type] => vegetable
// )
// )

Com a nova sintaxe para desestruturar uma matriz significa que agora há simetria entre construção de matriz e desestruturação, o que deve tornar mais claro qual é a função da sintaxe:

list($a, $b, $c) = array(1, 2, 3);
[$a, $b, $c] = [1, 2, 3];

list("a" => $a, "b" => $b, "c" => $c) = array("a" => 1, "b" => 2, "c" => 3);
["a" => $a, "b" => $b, "c" => $c] = ["a" => 1, "b" => 2, "c" => 3];

list($a, $b) = array($b, $a);
[$a, $b] = [$b, $a];

Acredito que com esse exemplo acima você deva ter conseguido sacar a diferença na simetria entre a nova e antiga sintaxe. Mas saiba que devido a questões de implementação, e por razões de consistência, list() não pode ser aninhado dentro de [], nem vice-versa:

// Isto não é permitido:
list([$a, $b], [$c, $d]) = [[1, 2], [3, 4]];

// Isto também não é permitido:
[list($a, $b), list($c, $d)] = [[1, 2], [3, 4]];

// Isso, no entanto, é permitido:
[[$a, $b], [$c, $d]] = [[1, 2], [3, 4]];

A Desestruturação de matriz simétrica é um termo incrivelmente confuso para um conceito simples, a simetria entre construção e desestruturação é uma característica de muitas outras linguagens. Um exemplo seria o código $array = [1, 2, 3], que é válido ECMAScript 6 e comportar-se de forma idêntica em PHP.
Espero ter ajudado com este post e qualquer sugestão ou dúvida deixe seu comentário.

Referências.
php.net
sebastiandedeyne.com
wiki.php.net
laracasts.com