Como obter uma matriz de "chave" específica em uma matriz multidimensional sem looping

115

Vamos supor que eu tenha a seguinte matriz multidimensional (recuperada do MySQL ou de um serviço):

array(
    array(
        [id] => xxx,
        [name] => blah
    ),
    array(
        [id] => yyy,
        [name] => blahblah
    ),
    array(
        [id] => zzz,
        [name] => blahblahblah
    ),
)

Podemos obter um array de ids em uma chamada de função php " embutida "? ou uma linha de código?
Estou ciente do loop tradicional e recebo o valor, mas não preciso disso:

foreach($users as $user) {
    $ids[] = $user['id'];
}
print_r($ids);

Talvez alguns array_map()e call_user_func_array()possam fazer a mágica.

ifaour
fonte
"Podemos obter uma matriz de ids em uma chamada de função?" sim, mas você terá que escrever a função
:)
@ BorisGuéry, eu quis dizer built-in funções :-)
ifaour
2
PS: Sei que posso escrever foreach($users as $user) {$ids[] = $user['id'];}em uma linha! mas você sabe o que quero dizer / preciso :-)
ifaour
@Eugene, preciso do array para outras coisas, obviamente. E, novamente, isso é apenas para se divertir e aprender novos atalhos em PHP.
ifaour

Respostas:

261

Desde o php 5.5, você pode usar array_column:

$ids = array_column($users, 'id');

Esta é a opção preferida em qualquer projeto moderno. No entanto, se você deve suportar php> 5.5, existem as seguintes alternativas:

Desde o php 5.3, você pode usar array_mapcom uma função anônima, como esta:

$ids = array_map(function ($ar) {return $ar['id'];}, $users);

Antes (Tecnicamente php 4.0.6+) , você deve criar uma função anônima com create_function:

$ids = array_map(create_function('$ar', 'return $ar["id"];'), $users);
phihag
fonte
bom, agora se houver uma função nativa que é semelhante ao function ($ar) {return $ar['id'];}valor de retorno da chave, isso seria incrível! :-)
ifaour
1
bem, esta não é uma função "tudo em um", mas Closure (funções anônimas) são um conceito muito poderoso que pode ser usado para tal processamento, você gostaria de saber como usá-los.
Boris Guéry
E se eu também quiser pegar a chave? Suponha: $ arr = ['bola' => ['cesta' => 5]]; Eu quero obter: $ ball = ['ball' => 5];
Angger,
2
@Angger Então você tem uma pergunta diferente desta. Sinta-se à vontade para perguntar, desde que você mencione em detalhes o comportamento que espera, por exemplo, o que aconteceria se a entrada fosse ['ball' => ['golf' => 7, 'basket' => 5, 'soccer' => 6], 'shuttle' => ['badminton' => 1]].
phihag
Desde o PHP7.4, você pode usar array_mapcom uma função de seta:$ids = array_map(fn ($ar) => $ar['id'], $users);
user3601546
13

PHP 5.5+

Iniciando o PHP5.5 + você tem array_column () disponível para você, o que torna todos os itens abaixo obsoletos.

PHP 5.3+

$ids = array_map(function ($ar) {return $ar['id'];}, $users);

A solução @phihag funcionará perfeitamente no PHP a partir do PHP 5.3.0, se você precisar de suporte antes disso, você precisará copiar esse wp_list_pluck.

PHP <5.3

Wordpress 3.1+

No Wordpress existe uma função chamada wp_list_pluck Se você estiver usando o Wordpress que resolve seu problema.

PHP <5.3

Se você não estiver usando o Wordpress , como o código é open source, você pode copiar e colar o código em seu projeto (e renomear a função para algo de sua preferência, como array_pick). Veja a fonte aqui

Norris
fonte
3

Se idfor a primeira chave na matriz, isso fará:

$ids = array_map('current', $users);

Você não deve necessariamente confiar nisso. :)

deceze
fonte
-1

Você também pode usar array_reduce()se preferir uma abordagem mais funcional

Por exemplo:

$userNames = array_reduce($users, function ($carry, $user) {
    array_push($carry, $user['name']);
    return $carry;
}, []);

Ou se você gosta de ser chique,

$userNames = [];
array_map(function ($user) use (&$userNames){
    $userNames[]=$user['name'];
}, $users);

Este e todos os métodos acima se repetem nos bastidores;)

Muraguri E
fonte
Seu primeiro exemplo não retornará um array, apenas o último valor encontrado para $ user ['name'] no array. Você precisa empurrar / anexar ao $ carry e retornar o $ carry conforme você avança.
Progrock