PHP array_column 引發的一個小問題

xianyunyehe發表於2018-09-05

array_column引發的一個問題

今天使用php陣列array_column處理一個資料的時候,出現了一些小問題。

先簡單的介紹下array_column.

array array_column ( array $input , mixed $column_key [, mixed $index_key = null ] )

array_column — 返回陣列中指定的一列

array_column() 返回input陣列中鍵值為column_key的列, 如果指定了可選引數index_key,那麼input陣列中的這一列的值將作為返回陣列中對應值的鍵。

$items = array(
    [
        "uid"=>1,
        "pid"=>0,
        "views"=>100
    ],
    [
        "uid"=>2,
        "pid"=>1,
        "views"=>200
    ],
    [
        "uid"=>3,
        "pid"=>0,
        "views"=>300
    ],
    [
        "uid"=>4,
        "pid"=>0,
        "views"=>400
    ],
    [
        "uid"=>5,
        "pid"=>3,
        "views"=>500
    ]
);

array_column($items,'uid');[1,2,3,4,5];
array_column($items,'uid','view');//[100=>1,200=>2,300=>3,400=>4,500=>5];

上面的程式碼可以看到,這個陣列可以幫助我們從一個多維陣列中返回指定的key的資料。

有些時候,我們會配合array_search 查詢多維陣列的元素。

array_search('3',array_column($items,'uid'));//uid =3所在的資料

現在開始說下今天遇到的問題,今天有一個需求,需要統計上面陣列中的資料,就是將pid 不等於的item 中的view 加到對應uid的views中去。舉個例子,uid =1 的view是100.它有一個子元素uid =2 ,需要把uid =2 的view 加到uid =1 到views上。以此類推。這個需求首先想到的是遍歷陣列,然後查詢每個item中的pid。如果不是0,然後用這個pid 當作uid。去查詢pid所在的索引,然後將當前值加上去,然後刪掉該記錄。

程式碼如下

array_walk($items,function ($item,$key) use(&$items){
    $uid = $item['uid'];
    //當前item的pid
    $pid = $item['pid'];
    //父id的在items中的索引
    $pidIndex = array_search($pid,array_column($items,'uid'));
    if($pid !== 0 && false !== $pidIndex) {
        //sum到父id記錄中
        $items[$pidIndex]['views'] += $item['views'];
        unset($items[$key]);
    }
});

初看,沒有啥太大的問題。其實是有問題的。但是由於對array_column 太熟悉,透過Xdebug發現就會出現了問題。

因為array_column 返回的陣列,是索引陣列。而非關聯。如果我們不刪資料的話,上面程式碼是沒問題的。但是我們刪除了item資料,原來的items 就會變成關聯陣列了。

array_column($items,'uid');//[1,2,3,4,5]
$items = [[],[],[],[]];
unset($items[1]);
//items 變成
[0=>[],2=>[],3=>[]]

當我們再使用array_column 就拿不到對應的index了。

上面的程式碼可以修改成如下

array_walk($items,function ($item,$key) use(&$items){
    $uid = $item['uid'];
    $pid = $item['pid'];
    $row = array_combine(array_keys($items),array_column($items,'uid'));
    $pidIndex = array_search($pid,$row );
    if($pid !== 0 && false !== $pidIndex) {
        $items[$pidIndex]['views'] += $item['views'];
        unset($items[$key]);
    }
});

一般情況下,我們使用array_column 不會有啥問題。如果改變了裡面的index,就會出問題。所以如果需要保持key不變的情況下。可以使用array_combinearray_keys

array_combine(array_keys($items),array_column($items,'uid'));

記錄一下。希望以後遇到同樣的問題的童鞋可以找到方案

本作品採用《CC 協議》,轉載必須註明作者和本文連結
閒雲野鶴

相關文章