在保持秩序的同时展平多维对象

时间:2016-09-16 13:50:01

标签: php

我想压扁一个物体。这是我到目前为止所得到的:

{
    "1": {
        "id": 1,
        "name": "parent",
        "children": {
            "4": {
                "id": 4,
                "name": "child1",
                "parent": 1
            },
            "5": {
                "id": 5,
                "name": "child2",
                "parent": 1
            }
        }
    }, 
    "2":{
        "id": 2,
        "name": "parent2"
    }
}

这就是我想要完成的事情。所以保持相同的顺序,但要平整对象:

{
    "1": {
        "id": 1,
        "name": "parent",
    },
    "4": {
        "id": 4,
        "name": "child1",
        "parent": 1
    },
    "5": {
        "id": 5,
        "name": "child2",
        "parent": 1
    }, 
    "2": {
        "id": 2,
        "name": "parent2"
    }
}

到目前为止,我还没有找到解决方法。我尝试过一项没有太大成功的功能:

protected function _flattenObject($array)
{
    static $flattened = [];
    if(is_object($array) && count($array) > 0)
    {
        foreach ($array as $key => $member) {
            if(!is_object($member))
            {
                $flattened[$key] = $member;
            } else
            {
                $this->_flattenObject($member);
            }
        }
    }
    return $flattened;
}

对我来说,最困难的部分是保持相同的顺序(儿童低于其父母)。上面提到的功能也删除了所有对象,并且几乎只保留了键的值,因此它根本没有取得巨大成功。

希望有人在这里知道一个很好的解决方案。

顺便说一下,我想要这种扁平结构的原因是因为我必须使用的系统,在处理多维数组和对象时遇到了麻烦。我仍然希望显示一个层次结构,这可以通过我描述的展平结构实现,因为对象实际上包含一个"级别"关键,所以我可以给他们一些基于"级别"同时仍然出现在他们的父母之下。

编辑: JSON似乎没有效果,所以我对它进行了一些修改。

2 个答案:

答案 0 :(得分:1)

主要问题似乎是你没有对递归函数的返回结果做任何事情。除非在方法中使用static做了一些我不知道的魔法......

所以这一节:

        if(!is_object($member))
        {
            $flattened[$key] = $member;
        } else
        {
            // What happens with the returned value?
            $this->_flattenObject($member);
        }

应该更像这样:

        if(!is_object($member))
        {
            $flattened[$key] = $member;
        } else
        {
            // Add the returned array to the array you already have
            $flattened += $this->_flattenObject($member);
        }

答案 1 :(得分:0)

这是有效的代码。它为对象添加了一个“级别”字段,以表示它们原始层次结构中的深度级别。

<?php

$obj = json_decode('[{
    "id": 1,
    "name": "parent",
    "children": [{
        "id": 4,
        "name": "child1",
        "parent": 1
    }, {
        "id": 5,
        "name": "child2",
        "parent": 1
    }]
}, {
    "id": 2,
    "name": "parent2"
}]');


function _flattenRecursive($array, &$flattened, &$level)
{
    foreach ($array as $key => $member) {
        $insert = $member;
        $children = null;
        if (is_array($insert->children)) {
            $children = $insert->children;
            $insert->children = array();
        }
        $insert->level = $level;
        $flattened[] = $insert;
        if ($children !== null) {
            $level++;
            _flattenRecursive($children, $flattened, $level);
            $level--;
        }
    }
}

function flattenObject($array)
{
    $flattened = [];
    $level = 0;

    _flattenRecursive($array, $flattened, $level);

    return $flattened;
}

$flat = flattenObject($obj);

var_dump($flat);

?>