Pergunta

Digamos, por exemplo você só consultada uma base de dados e que você recebeu esta matriz 2D.

$results = array(
    array('id' => 1, 'name' => 'red'  , 'spin' =>  1),
    array('id' => 2, 'name' => 'green', 'spin' => -1),
    array('id' => 3, 'name' => 'blue' , 'spin' => .5)
);

Sinto-me frequentemente escrever laços assim.

foreach($results as $result)
    $names[] = $result['name'];

As minhas perguntas é se existe uma maneira de obter essa matriz $ nomes sem usar um loop? Utilizar funções de chamada de retorno contam como usar um loop.

Aqui está um exemplo mais genérico de obter todos os campos.

foreach($results as $result)
    foreach($result as $key => $value)
        $fields[$key][] = $value;
Foi útil?

Solução

A partir de 20 de junho em PHP-5.5, há uma nova função array_column

Por exemplo:

$records = array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe'
    ),
    array(
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith'
    ),
    array(
        'id' => 5342,
        'first_name' => 'Jane',
        'last_name' => 'Jones'
    ),
    array(
        'id' => 5623,
        'first_name' => 'Peter',
        'last_name' => 'Doe'
    )
);


$firstNames = array_column($records, 'first_name');
print_r($firstNames);

retornará

Array
(
    [0] => John
    [1] => Sally
    [2] => Jane
    [3] => Peter
)

Há ainda mais exemplos no link acima mencionado.

Outras dicas

Votei @ resposta de Devon, porque não há realmente uma maneira de fazer o que você está pedindo com uma função built-in. O melhor que você pode fazer é escrever o seu próprio:

function array_column($array, $column)
{
    $ret = array();
    foreach ($array as $row) $ret[] = $row[$column];
    return $ret;
}

Começando PHP 5.3, você pode usar esta chamada muito com a função lambda:

$names = array_map(function ($v){ return $v['name']; }, $results);

Isso irá retornar variedade cortado pela dimensão 'nome'.

Em termos simples, não.

Você vai precisar usar um loop ou uma função de retorno de chamada como array_walk .

Eu fiz mais pesquisas sobre isso e descobriu que Ruby e protótipo ambos têm uma função que faz este chamado array_pluck , 2 . É interessante que array_map tem um segundo uso que lhe permite fazer o inverso do que eu quero fazer aqui. Eu também achei um PHP classe alguém está escrevendo para protótipos manipulação emular de matrizes.

Eu vou fazer um pouco mais a cavar em volta e se eu não encontrar qualquer outra coisa que eu vou trabalhar em um patch para enviar a lista de discussão internals@lists.php.net e ver se eles vão adicionar array_pluck.

Para aqueles de vocês que não pode atualizar para PHP5.5 agora e precisa esta função, aqui é uma implementação do array_column.

function array_column($array, $column){
    $a2 = array();
    array_map(function ($a1) use ($column, &$a2){
        array_push($a2, $a1[$column]);
    }, $array);
    return $a2;
}

Se você estiver executando uma versão do PHP antes de 5.5 e array_column(), você pode usar a substituição oficial em PHP comum:

https://github.com/ramsey/array_column

Eu acho que isso vai fazer o que quiser

array_uintersect_uassoc

Você teria que fazer algo assim

$results = array(
    array('id' => 1, 'name' => 'red'  , 'spin' =>  1),
    array('id' => 2, 'name' => 'green', 'spin' => -1),
    array('id' => 3, 'name' => 'blue' , 'spin' => .5)
);
$name = array_uintersect_uassoc( $results, array('name' => 'value')  , 0, "cmpKey");
print_r($name);

//////////////////////////////////////////////////
// FUNCTIONS
//////////////////////////////////////////////////
function cmpKey($key1, $key2) {
  if ($key1 == $key2) {
    return 0;
  } else {
    return -1;
  }
}

No entanto, eu não tenho acesso a PHP5 então eu não testei isso.

Você poderia fazer:

$tmp = array_flip($names);
$names = array_keys($tmp);

Este é alternativa função rápida de array_column ()

if(!function_exists('array_column')) {
    function array_column($element_name) {
        $ele =   array_map(function($element) {
            return $element[$element_name];
        }, $a);
        return  $ele;
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top