簡體   English   中英

將多維 PHP 數組切分到其元素之一

[英]Slicing a multi-dimensional PHP array across one of its elements

舉例來說,您剛剛查詢了一個數據庫並收到了這個二維數組。

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

截至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
)

在上面提到的鏈接中有更多的例子。

我投了@Devon的回復,因為實際上沒有辦法用內置函數做你想要的。 你能做的最好就是寫自己的:

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

從PHP 5.3開始,你可以使用lambda函數調用這個漂亮的調用:

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

這將返回按“名稱”維度切片的數組。

簡單地說,不。

您將需要使用循環或回調函數,如array_walk

我對此做了更多的研究,發現ruby和prototype都有一個叫做array_pluck的函數, 2 有趣的是, array_map有第二次使用,允許你做我想做的反向。 我還發現了一個PHP 類,有人正在編寫模擬原型對數組的操作。

我將要進行更多的挖掘,如果我找不到任何其他東西,我將在修補程序上提交到internals@lists.php.net郵件列表,看看他們是否會添加array_pluck。

對於那些現在無法升級到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;
}

如果您在5.5和array_column()之前運行PHP版本,則可以使用普通PHP中的官方替換:

https://github.com/ramsey/array_column

你可以這樣做:

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

我想這會做你想要的

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所以我沒有測試過這個。

這是array_column()的快速功能替代

if(!function_exists('array_column')) {
    function array_column($element_name) {
        $ele =   array_map(function($element) {
            return $element[$element_name];
        }, $a);
        return  $ele;
    }
}

其他選擇

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM