2016-01-30 125 views
2

合并不同的值我有一个数组:滤波器2名维阵列和PHP

$arr = [ 
    ['id'=>1, 'name'=>'Peter', 'age'=>28], 
    ['id'=>1, 'name'=>'David', 'age'=>28], 
    ['id'=>2, 'name'=>'John', 'age'=>34], 
    ['id'=>3, 'name'=>'Smith', 'age'=>36], 
    ['id'=>3, 'name'=>'Smith', 'age'=>28], 
]; 

欲通过柱的“id”过滤它,并合并不同的值。我需要输出:

$arr = [ 
    ['id'=>1, 'name'=>'Peter,David', 'age'=>28], 
    ['id'=>2, 'name'=>'John', 'age'=>34], 
    ['id'=>3, 'name'=>'Smith', 'age'=>'36,28'] 
]; 

是否有任何PHP函数(如:array_filter,array_walk,array_map,...)要做到这一点,没有下文循环的代码?

function combine_row($arr){ 
    $last = null; 
    foreach ($arr as $key => $a){ 
     if ($a['id']==$last['id']){ 
      foreach ($a as $k=>$v) { 
       if($v!==$last[$k]) { 
        $arr[$key][$k].=','.$last[$k]; 
       } 
      } 
      unset($arr[$key-1]); 
     } 
     $last = $a; 
    } 
    return $arr; 
} 

感谢您的帮助!

+0

Phong,你解决了吗?让我知道如果我应该对我的答案进行更改 – Michael

+0

对不起,迈克尔,我没有回来查看您的答案,因为我找到了通过使用Group_concat从mysql中修复它的方法。无论如何,你的答案是如此完美。我将其标记为已接受的答案。谢谢! –

回答

0

下面是一个使用了更实用的风格的解决方案。基本上只有很多内置的array_*功能。这将确保较少的副作用,使您的代码更容易出错。

代码首先找到所有唯一的_id_s。然后它会过滤数据并最终加入它。

$result = array_map(
    function ($id) use ($arr) { 
     return array_map(function ($data) { 
       if (is_array($data)) return join(",", array_unique($data)); 
       return $data; 
      }, array_reduce(
       array_filter($arr, function ($item) use ($id) { return $id === $item["id"]; }), 
       function ($result, $set) { return $result = array_filter(array_merge_recursive($result, $set)); }, [ ] 
      ) 
     ); 
    }, 
    array_unique(array_column($arr, "id")) 
); 

print_r($result); 

输出:

Array 
(
    [0] => Array 
     (
      [id] => 1 
      [name] => Peter,David 
      [age] => 28 
     ) 

    [2] => Array 
     (
      [id] => 2 
      [name] => John 
      [age] => 34 
     ) 

    [3] => Array 
     (
      [id] => 3 
      [name] => Smith 
      [age] => 36,28 
     ) 

) 

使用a chainable apigithub可以实现更可读的代码:

$result = arr($arr) 
    ->column("id") 
    ->unique() 
    ->map(
     function ($id) use ($arr) { 
      return arr($arr) 
       ->filter(function ($item) use ($id) { return $id === $item["id"]; }) 
       ->reduce(function ($result, $set) { return array_filter(array_merge_recursive($result, $set)); }, []) 
       ->map(function ($data) { 
        if (is_array($data)) return arr($data)->unique()->join(",")->toArray(); 
        return $data; 
       })->toArray(); 
     } 
    )->toArray(); 
-2

试试这个

function merge_multidimensional($arr) { 
$out = array(); 
foreach ($arr as $key => $value){ 
    $out[] = (object)array_merge((array)$arr2[$key], (array)$value); 
} 
return $out; 

}

+0

我试过了,但没有帮助 –

-1

入住这下面的代码,

function getMergerArray($arr) { 
    $newArr = array(); 
    foreach ($arr as $key => $value) { 
     $id = $value['id']; 
     $name = $value['name']; 
     $age = $value['age']; 
     if (array_key_exists($id, $newArr)) { 
      if (!in_array($name, $newArr[$id]['name'])) { 
       $newArr[$id]['name'][] = $name; 
      } 
      if (!in_array($age, $newArr[$id]['age'])) { 
       $newArr[$id]['age'][] = $age; 
      } 
      continue; 
     } 
     $newArr[$id]['name'][] = $name; 
     $newArr[$id]['age'][] = $age; 
    } 
    foreach ($newArr as $key => $value) { 
     $newArr[$key] = array(
      'id' => $key, 
      'name' => implode(', ', $value['name']), 
      'age' => implode(', ', $value['age']), 
     ); 
    } 
// echo '<pre>'; 
// print_r($newArr); 
// echo '</pre>'; 
    return $newArr; 
} 
+0

嗨@deceze,为什么这个答案被投票了?原因将在未来发布新答案时帮助我,并将帮助引用此答案的其他人。先谢谢你 :) –

0
$result = []; 
foreach ($arr as $person) { 
    foreach ($person as $key => $value) { 
     if ($key == 'id') { 
      $result[$person['id']][$key] = $value; 
     } else { 
      $result[$person['id']][$key][] = $value; 
     } 
    } 
} 

魔术真的是$result[$person['id']],该群体具有相同的所有项目id很自然地进入相同的结果数组。这也为多个值创建了数组,而不是仅仅连接字符串,这是一个非常好用的数据结构。如果你只想要唯一的值,请在那里输入array_unique。如果您确实需要用逗号加入项目,请在末尾使用join(',', ..)