迭代平面数组并在PHP中构建json

时间:2017-11-16 01:25:15

标签: php arrays

我有一个从目录结构动态构建的平面文件数组,这里可以看到这样的输出样本;

Array (
    [0] => filename-in-root.png
    [1] => another-filename-in-root.png
    [directory.subdirectory.0] => logo-of-some-sort.jpeg
    [directory.subdirectory.1] => image-of-queen.jpg
    [anotherdirectory.0] => a-screenshot-png
    [anotherdir.0] => a-lovely-picture.png
    [nextdirectory.0] => me-giving-the-bird.png
)

然后我正在做的是将此输出提供给另一个函数以生成json输出,我可以将其插入到我的javascript组件中。

它适用于根目录中的文件,如果目录/子目录中只有1个文件...但是当向目录和子目录添加多个文件时,它会导致目录结构再次输出,如下所示;

[
    [0,"/","/",false,1],
    [1,"/filename-in-root.png","filename-in-root.png",true,1],
    [2,"/another-filename-in-root.png","another-filename-in-root.png",true,1],
    [3,"/directory","Directory",false,1],
    [4,"/directory/subdirectory","Subdirectory",false,2],
    [5,"/directory/subdirectory/logo-of-some-sort.jpeg","logo-of-some-sort.jpeg",true,3],
    [6,"/directory","Directory",false,1],
    [7,"/directory/subdirectory","Subdirectory",false,2],
    [8,"/directory/subdirectory/image-of-queen.jpg","image-of-queen.jpg",true,3],
    and so on.........
]

如您所见,项目6和7不应该在那里,因为项目8已经标记在正确的目录中,最后的数字表示它应该有多少缩进。

用于生成此代码的代码如下;

function generateJson($flatArray)
{
    $arrayId = 1;
    $final_array = [[0, '/', '/', false, 1]];
    ksort($flatArray, SORT_STRING);

    foreach ($flatArray as $key => $val) {
        $exploded_key = explode('.', $key);
        foreach ($exploded_key as $k => $v) {
            if ($k == sizeof($exploded_key)-1) {
                $count = 1;
                for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                    $count++;
                }
                $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k)) . '/' . $val, $val, true, $count];
                $arrayId++;
            } else {
                $count = 1;
                for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                    $count++;
                }
                $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k + 1)), ucfirst($v), false, $count];
                $arrayId++;
            }
        }
    }

    return json_encode($final_array);
}

我坚持这一点......任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:1)

在将任何元素附加到$final_arrayjson_encode d)之前,我们可以检查它是否已存在以避免重复。

我们也可以减少代码中的重复:

function generateJson($flatArray)
{
    $arrayId = 1;
    $final_array = [[0, '/', '/', false, 1]];
    $final_paths = []; // New array to store paths
    ksort($flatArray, SORT_STRING);
    foreach ($flatArray as $key => $val) {
        $exploded_key = explode('.', $key);
        foreach ($exploded_key as $k => $v) {
            $count = 1;
            // Changes start from here (in addition to initializing $final_paths array above)
            $end = count(array_slice($exploded_key, 0, $k));
            for ($i = 0; $i < $end; $i++) {
                $count++;
            }
            // The only statement changed is wrapped with the if-statement
            if ($k == sizeof($exploded_key)-1) {
                $new_element = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k)) . '/' . $val, $val, true, $count];
            } else {
                $new_element = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k + 1)), ucfirst($v), false, $count];
            }
            // *This is it*: append the element ONLY IF it is not in the array
            if(!in_array($new_element[1], $final_paths)) {
                $final_paths[] = $new_element[1];
                $final_array[] = $new_element;
                $arrayId++;
            }
        }
    }
    return json_encode($final_array);
}

也许不是最好的解决方案(从运行时的角度来看),但它应该可行。