21

例如,您刚刚查询了一个数据库并收到了这个二维数组。

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

我经常发现自己在写这样的循环。

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

我的问题是有没有一种方法可以在不使用循环的情况下获取这个数组 $names?使用回调函数算作使用循环。

这是获取每个字段的更通用示例。

foreach($results as $result)
    foreach($result as $key => $value)
        $fields[$key][] = $value;
4

11 回答 11

23

截至 6 月 20 日,PHP-5.5 中有一个新函数array_column

例如:

$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);

将返回

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

上述链接中还有更多示例。

于 2013-03-21T18:51:53.637 回答
14

我对@Devon 的回复投了赞成票,因为确实没有办法使用内置函数来完成您所要求的事情。你能做的最好的就是写你自己的:

function array_column($array, $column)
{
    $ret = array();
    foreach ($array as $row) $ret[] = $row[$column];
    return $ret;
}
于 2008-10-02T17:13:38.587 回答
7

从 PHP 5.3 开始,您可以将这个漂亮的调用与 lambda 函数一起使用:

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

这将返回按“名称”维度切片的数组。

于 2012-11-26T09:04:51.053 回答
5

简单地说,没有。

您将需要使用循环或回调函数,如array_walk

于 2008-10-02T16:55:30.347 回答
2

我对此进行了更多研究,发现 ruby​​ 和原型都有一个称为array_pluck 2的函数。有趣的是,它array_map还有第二个用途,可以让你做与我在这里想做的相反的事情。我还发现有人正在编写一个 PHP来模拟数组的原型操作。

我将做更多的挖掘工作,如果我没有找到任何其他东西,我将制作一个补丁提交到 internals@lists.php.net 邮件列表,看看他们是否会添加 array_pluck。

于 2008-10-03T23:07:25.703 回答
2

对于那些现在无法升级PHP5.5并需要此功能的人,这里是array_column.

function array_column($array, $column){
    $a2 = array();
    array_map(function ($a1) use ($column, &$a2){
        array_push($a2, $a1[$column]);
    }, $array);
    return $a2;
}
于 2013-10-04T18:15:16.760 回答
1

如果您运行的是 5.5 和 5.5 之前的 PHP 版本array_column(),则可以使用普通 PHP 中的官方替换:

https://github.com/ramsey/array_column

于 2014-07-07T17:38:09.107 回答
0

我认为这会做你想要的

array_uintersect_uassoc

你必须做这样的事情

$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;
  }
}

但是,我无权访问 PHP5,所以我没有对此进行测试。

于 2008-10-02T19:12:05.963 回答
0

你可以这样做:

$tmp = array_flip($names);
$names = array_keys($tmp);
于 2013-03-26T19:08:41.313 回答
0

这是 array_column() 的快速函数替代

if(!function_exists('array_column')) {
    function array_column($element_name) {
        $ele =   array_map(function($element) {
            return $element[$element_name];
        }, $a);
        return  $ele;
    }
}
于 2014-08-11T08:52:17.543 回答
0

其他选择

 function transpose(array $array): array
 {
     $out = array();
     foreach ($array as $rowkey => $row) {
        foreach ($row as $colkey => $col) {
                $out[$colkey][$rowkey] = $col;
         }
     }
        return $out;
 }

 function filter_columns(array $arr, string ...$columns): array
 {
     return array_intersect_key($arr, array_flip($columns));
 }

测试

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

 var_dump(filter_columns(transpose($results),'name'));
 var_dump(filter_columns(transpose($results),'id','name'));
 var_dump(filter_columns(transpose($results),'id','spin'));
于 2021-12-28T06:40:00.117 回答