Объединить ассоциативный массив на основе ключей
Всем привет. Мне нужно из массива
$array = [
[
"module" => "articles",
"read" => true,
"edit" => false,
"create" => false,
"delete" => false,
], [
"module" => "articles",
"read" => false,
"edit" => false,
"create" => true,
"delete" => false,
], [
"module" => "articles",
"read" => false,
"edit" => true,
"create" => false,
"delete" => false,
], [
"module" => "user",
"read" => true,
"edit" => false,
"create" => false,
"delete" => false,
], [
"module" => "user",
"read" => false,
"edit" => false,
"create" => true,
"delete" => false,
]
];
получить такой массив
$result = [
[
"module" => "articles",
"read" => true,
"edit" => true,
"create" => true,
"delete" => false,
], [
"module" => "users",
"read" => true,
"edit" => false,
"create" => true,
"delete" => false,
],
];
т.е. если при объединении один из ключей массива отсутствует, то он false.
Пока что написал такой код, он только объединяет
$result = array_reduce($rows, function($accumulator, $item) {
$index = $item['module'];
if (!isset($accumulator[$index])) {
$accumulator[$index] = [
"module" => $index,
"read" => $item['read'],
"edit" => $item['edit'],
"create" => $item['create'],
"delete" => $item['delete'],
];
}
array_intersect_key(
$accumulator, $item
);
return $accumulator;
});
Ответы (2 шт):
Автор решения: Проста Miha
→ Ссылка
Попробуй вот, это очень не логический код, но помог как мог)
$array = [
[
"module" => "articles",
"read" => true,
"edit" => false,
"create" => false,
"delete" => false,
], [
"module" => "articles",
"read" => false,
"edit" => false,
"create" => true,
"delete" => false,
], [
"module" => "articles",
"read" => false,
"edit" => true,
"create" => false,
"delete" => false,
], [
"module" => "user",
"read" => true,
"edit" => false,
"create" => false,
"delete" => false,
], [
"module" => "user",
"read" => false,
"edit" => false,
"create" => true,
"delete" => false,
]
];
$newArray = [];
for ($i = 0; $i < count($array); $i++) {
$module = $array[$i]["module"];
if (!isset($newArray[$module])) {
$newArray[$module] = $array[$i];
}
}
for ($i = 0; $i < count($array); $i++) {
foreach($newArray as $key => $value) {
if ($array[$i]["module"] == $value["module"]) {
$newArray[$key]["read"] = $array[$i]["read"] == true ? true : $newArray[$key]["read"];
$newArray[$key]["edit"] = $array[$i]["edit"] == true ? true : $newArray[$key]["edit"];
$newArray[$key]["create"] = $array[$i]["create"] == true ? true : $newArray[$key]["create"];
$newArray[$key]["delete"] = $array[$i]["delete"] == true ? true : $newArray[$key]["delete"];
}
}
}
var_dump($newArray);
Автор решения: Laukhin Andrey
→ Ссылка
Если я правильно понял суть, то атрибуты объединяются по дизъюнкции (логическое ИЛИ). В таком случае, немного подправив Ваш код, получим нужный результат:
$result = array_reduce($array, function($acc, $item) {
$index = $item['module'];
if (!isset($acc[$index])) $acc[$index] = $item;
else
foreach($item as $k => $v)
if($k !== 'module')
$acc[$index][$k] = !empty($acc[$index][$k]) || $v;
return $acc;
});
$result = array_values($result); //если требуется индексный массив