将分隔的字符串数组转换为key&数组。值

时间:2017-09-12 10:47:05

标签: php arrays string

我有这个数组的例子:

$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,
            ],
        ]
    ]
];

我无法弄清楚如何做到这一点。

2 个答案:

答案 0 :(得分: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 :(得分:0)

可以通过数组引用轻松完成:

tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

测试结果:

$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;
}

P.S。我没有意识到我花了10分钟来调试关于{ "dashboard": { "read": true, "section1": { "read": true } }, "members": { "member": { "create": false, "read": true, "view": { "update": true, "section2": { "delete": false }, "0": true } } } }

的特殊条件