PHP сгруппировать массив по значению
Есть массив вида
$array = [
['group_id' => 2, 'element_id' => 3],
['group_id' => 2, 'element_id' => 2],
['group_id' => 1, 'element_id' => 1],
];
Нужно сгруппировать его элементы по group_id чтобы на выходе получился вот такой массив:
$result = [['group_id' => 2, 'element_id'=> [3,2]], ['group_id' => 1,'element_id'=>[1]]];
Важно что бы на получившийся массив имел точно такую структуру как я описал. Кто в курсе как красиво это реализовать?
UPD. Хорошее рабочее решение предложил тов. Becouse. Чуть подправленный вариант (более лаконичный) приведу ниже:
function group_by($array, $key, $res)
{
$return = array();
foreach($array as $val) {
$return[$key][$val[$key]][$res][] = $val[$res];
}
$func = function ($array, $first, $second) {
$result=array();
foreach($array[$first] as $key=>$val){
$a=array();
$a[$first]=$key;
$a[$second]=$val[$second];
$result[]=$a;
}
return $result;
};
return $func($return, $key, $res);
}
Ответы (4 шт):
Автор решения: Denis640Kb
→ Ссылка
<?php
$array = [
['group_id' => 2, 'element_id' => 3],
['group_id' => 2, 'element_id' => 2],
['group_id' => 1, 'element_id' => 1],
];
$result = [];
foreach ($array as $item){
if(count($result) > 0){
$have = 0;
foreach ($result as $key=>$val){
if (in_array($item['group_id'], $val)){
array_push($result[$key]['element_id'], $item['element_id']);
} else {
$have = 1;
}
}
if($have == 1){
$tempArr = [];
$tempArr['group_id'] = $item['group_id'];
$tempArr['element_id'] = array($item['element_id']);
array_push($result, $tempArr);
}
} else {
$tempArr = [];
$tempArr['group_id'] = $item['group_id'];
$tempArr['element_id'] = array($item['element_id']);
array_push($result, $tempArr);
}
}
print_r($result);
Автор решения: Bloom
→ Ссылка
<?php
$array = array(
array('group_id' => 2, 'element_id' => 3),
array('group_id' => 2, 'element_id' => 2),
array('group_id' => 1, 'element_id' => 1),
);
$result = [array('group_id' => '2', 'element_id'=> array('3','2')), array('group_id' => '1','element_id'=>array('1'))];
print_r($result);
echo '------';
$result1=array(array('group_id' => $array[0]['group_id'], 'element_id'=> array($array[0]['element_id'], $array[0]['group_id'])), array('group_id'=> $array[2]['group_id'], 'element_id'=>array($array[2]['element_id'])));
print_r($result1);
?>
Автор решения: becouse
→ Ссылка
Вот такой вариант.
Вспомогательная функция
function _group_by_elements($array, $first, $second){
$result=array();
foreach($array[$first] as $key=>$val){
$a=array();
$a[$first]=$key;
$a[$second]=$val[$second];
$result[]=$a;
}
return $result;
}
Основная функция
function _group_by($array, $key, $res) {
$return = array();
foreach($array as $val) {
$return[$key][$val[$key]][$res][] = $val[$res];
}
return _group_by_elements($return, $key, $res);
}
исходный преобразуем в
['group_id'=>[2=>['element_id'=> [3,2]], 1=>'element_id'=>[1]]]
Затем _group_by_elements в другой формат
[['group_id' => 2, 'element_id'=> [3,2]], ['group_id' => 1,'element_id'=>[1]]]
Пример
$list = [
['group_id' => 2, 'element_id' => 3],
['group_id' => 2, 'element_id' => 2],
['group_id' => 1, 'element_id' => 1],
];
$group=_group_by($list, 'group_id','element_id');
print_r($group);
Автор решения: u_mulder
→ Ссылка
$array = [
['group_id' => 2, 'element_id' => 3],
['group_id' => 2, 'element_id' => 2],
['group_id' => 1, 'element_id' => 1],
];
$result = [];
foreach ($array as $item) {
$groupId = $item['group_id'];
if (!isset($result[$groupId])) {
$result[$groupId] = ['group_id' => $groupId, 'element_id'=> []];
}
$result[$groupId]['element_id'][] = $item['element_id'];
}
print_r(array_values($result));