У меня есть массив, упомянутый ниже.
$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
)
);
Идеальный пример использования функции 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()
отбрасывает ключи и возвращает массив, индексированный с использованием последовательных числовых ключей, начинающихся с нуля (как указано в вопросе).
Просто используя 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()
удалить временные ассоциативные ключи из результирующего массива.
<?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);
Вы можете перебрать массив и сохранить все в отдельном массиве для группы. После этого вы можете создать выходной массив в нужном вам формате, например так:
$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);