Группировка и объединение массива в переполнении стека

У меня есть массив, упомянутый ниже.

$array = array(
'0' => array(
'names' => array(0 => 'Apple'),
'group' => 1
),
'1' => array(
'names' => array(0 => 'Mango'),
'group' => 1
),
'2' => array(
'names' => array(0 => 'Grapes'),
'group' => 1
),
'3' => array(
'names' => array(0 => 'Tomato'),
'group' => 2
),
'4' => array(
'names' => array(0 => 'Potato'),
'group' => 2
)
);

Я хочу получить результат таким образом, чтобы, если значение ключа массива «группа» было одинаковым, значения ключа «имена» должны быть объединены. Я хочу вывод, упомянутый ниже.

    $array = array(
'0' => array(
'names' => array(0 => 'Apple', 1 => 'Mango', 2 => 'Grapes'),
'group' => 1
),
'1' => array(
'names' => array(0 => 'Tomato', 1 => 'Potato'),
'group' => 2
)
);

-2

Решение

Идеальный пример использования функции PHP array_reduce():

$array = array_values(
array_reduce(
$array,
function (array $carry, array $item) {
// Extract the group name into a variable for readability
// and speed; it is used several times velow
$key = $item['group'];
// Initialize the group if it is the first entry in this group
if (! array_key_exists($key, $carry)) {
$carry[$key] = array(
'names' => array(),
'group' => $key,
);
}
// Add the new names to the group in the output array
$carry[$key]['names'] = array_merge($carry[$key]['names'], $item['names']);

// Return the partial result
return $carry;
},
array()
)
);

Код использует array_reduce() итеративно построить новый массив, который содержит ожидаемые значения.

Функция обратного вызова создает группу, если необходимо, затем объединяет имена обработанного элемента в существующую группу в результирующем массиве.

Массив, созданный с использованием array_reduce() индексируется с использованием значений groupв порядке их появления во входном массиве. Для размещенного массива их ключи будут 1 а также 2, Если вам не нужны ключи, удалите звонок array_values() получить небольшое улучшение в скорости и удобочитаемости.

Функция array_values() отбрасывает ключи и возвращает массив, индексированный с использованием последовательных числовых ключей, начинающихся с нуля (как указано в вопросе).

0

Другие решения

Просто используя group значения в качестве временных ассоциативных ключей, вы можете быстро определить (при итерации), если вы должны хранить всю строку данных, или просто добавить names значение для существующего подмассива.

* если данные вашего проекта могут содержать входные подмассивы с более чем одним names значение, вы должны обновить свой вопрос, чтобы уточнить эту возможность. (Бахрома Демо) (Fringe Demo2)

Код: (демонстрация)

foreach ($array as $row) {
if (!isset($result[$row['group']])) {
$result[$row['group']] = $row;
} else {
$result[$row['group']]['names'][] = $row['names'][0];
}
}

var_export(array_values($result));

Выход:

array (
0 =>
array (
'names' =>
array (
0 => 'Apple',
1 => 'Mango',
2 => 'Grapes',
),
'group' => 1,
),
1 =>
array (
'names' =>
array (
0 => 'Tomato',
1 => 'Potato',
),
'group' => 2,
),
)

Ты можешь использовать array_values() удалить временные ассоциативные ключи из результирующего массива.

0

<?php
//initialize our array
$array = array(
'0' => array(
'names' => array(0 => 'Apple'),
'group' => 1
),
'1' => array(
'names' => array(0 => 'Mango'),
'group' => 1
),
'2' => array(
'names' => array(0 => 'Grapes'),
'group' => 1
),
'3' => array(
'names' => array(0 => 'Tomato'),
'group' => 2
),
'4' => array(
'names' => array(0 => 'Potato'),
'group' => 2
)
);
//result will be here
$result = array();

foreach ($array as $key => $value) {
//check if we have keys group or names to avoid errors
if(!isset($value['group']) || !isset($value['names']))
continue;

//make a key in result array if its not exist
if(!isset($result[$value['group']]))
{
$result[$value['group']] = $value['names'];
}
else
{
//add a values to key if it exists
$result[$value['group']] = array_merge($result[$value['group']],
$value['names']);
//filter same values
$result[$value['group']] = array_values(array_unique($result[$value['group']]));
}
}
print_r($result);
-1

Вы можете перебрать массив и сохранить все в отдельном массиве для группы. После этого вы можете создать выходной массив в нужном вам формате, например так:

$groups = array();
foreach($array as $subArray) {
if (!array_key_exists($subArray['group'], $groups)) {
$groups[$subArray['group']] = array();
}
$groups[$subArray['group']] = array_merge($groups[$subArray['group']], $subArray['names']);
}

$result = array();
foreach($groups as $groupId => $group) {
$result[] = array(
'names' => $group,
'group' => $groupId,
);
}

print_r($result);
-1