Преобразовать массив строк, разделенных в массив ключей & ценности

У меня есть этот пример массива:

$roles = [
"dashboard.read" => true,
"dashboard.section1.read" => true,
"members.member.create" => false,
"members.member.read" => true,
"members.member.view.update" => true,
"members.member.view.section2.delete" => false,
"members.member.view" => true
];

и мне нужен метод для преобразования массивов аналогичной структуры в этот результат:

$roles = [
"dashboard" => [
"read" => true,
"section1" => [
"read" => true
]
],
"members" => [
"member" => [
"create" => false,
"read" => true,
"view" => [
"update" => true,
"section2" => [
"delete" => false
],
true,
],
]
]
];

Я не могу понять, как это сделать.

1

Решение

Для решения вашего вопроса я воспринял это как сложную задачу. Я добавил все детали прямо в код:

// your defined roles, as stated above
$roles = [
"dashboard.read" => true,
"dashboard.section1.read" => true,
"members.member.create" => false,
"members.member.read" => true,
"members.member.view.update" => true,
"members.member.view.section2.delete" => false,
"members.member.view" => true
];

// the magic array, which will have all the results later
$magic = array();

// iterate trough all the roles
foreach($roles as $key => $value) {
// split the roles and reverse the array, so we can start with setting the value
$roleNamePart = array_reverse(explode(".", $key));

// this array is used to recursive create all the array in itself
$magicCreationArray = array();

// iterate trough those role name parts starting at the "bottom"foreach($roleNamePart as $keypart) {

// if it is empty, it is really the bottom and you can set the value right there
if(empty($magicCreationArray)) {
$magicCreationArray[$keypart] = $value;

// if its not, it must be something inbetween, go one level up. its needed to create a temporary value for this, i guess
} else {
$tmp = $magicCreationArray;
unset($magicCreationArray);
$magicCreationArray[$keypart] = $tmp;
}
}
// merge all the data to the magic array, use array_merge_recursive so it does not override for example "dashboard"$magic = array_merge_recursive($magic, $magicCreationArray);
}

// here you go fam
print_r($magic);

Надеюсь, я смогу помочь вам с этим.

Приятно читать: http://php.net/manual/en/function.array-merge-recursive.php

1

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

Это легко сделать с помощью ссылок на массивы:

$input = [
"dashboard.read" => true,
"dashboard.section1.read" => true,
"members.member.create" => false,
"members.member.read" => true,
"members.member.view.update" => true,
"members.member.view.section2.delete" => false,
"members.member.view" => true
];

$output = [];

foreach($input as $key => $value){
$pointer =& $output;
$keyParts = explode(".", $key);
foreach(array_slice($keyParts, 0, -1) as $part){
if(!isset($pointer[$part])) $pointer[$part] = [];
$pointer =& $pointer[$part];

// special case: If $key is a.b.c.d and a.b is already defined, convert the a.b value into an array
if(!is_array($pointer)) $pointer = [$pointer];
}
$name = array_slice($keyParts, -1)[0];

// special case: If $key is a.b and a.b.c.d is already defined, append to the array rather than overwriting it
if(isset($pointer[$name])) $pointer[$name][] = $value;
else $pointer[$name] = $value;
}

Результат испытаний:

{
"dashboard": {
"read": true,
"section1": {
"read": true
}
},
"members": {
"member": {
"create": false,
"read": true,
"view": {
"update": true,
"section2": {
"delete": false
},
"0": true
}
}
}
}

Постскриптум Я не понимал, что мне потребовалось 10 минут, чтобы отладить специальное условие о members.member.view

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector