简体   繁体   English

遍历平面数组并在PHP中构建json

[英]Iterating over flat array and building json in PHP

I have a flat array of files that's dynamically built from a directory structure, a sample of such output can be seen here; 我有一个扁平的文件数组,这些文件是根据目录结构动态构建的,可以在此处看到此类输出的示例。

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
)

Then what im doing is feeding this output into another function to produce json output i can plug into my javascript component. 然后,即时通讯正在将这个输出馈送到另一个函数以产生json输出,我可以将其插入到我的javascript组件中。

It works great for files in the root, and also if there is only 1 file in a directory / subdirectory ... BUT when adding multiple files to directories and subdirectories, it causes the directory structure to be output again as seen below; 它对于根目录中的文件非常有用,并且如果目录/子目录中只有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.........
]

As you can see, item 6 and 7 shouldnt be there as item 8 is already marked in the right directory, the number at the end indicates how many indents it should have. 如您所见,第6项和第7项不应该存在,因为第8项已经在正确的目录中标记了,末尾的数字表示应该有多少个缩进。

The code im using to generate this is as follows; im用于生成此代码的代码如下:

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

Im so stuck on this ... any help would be greatly appreciated. 我对此非常执着...任何帮助将不胜感激。

Before appending any element to the $final_array (which is json_encode d), we can check if it already exists to avoid duplication. 在将任何元素附加到$final_array (即json_encode d)之前,我们可以检查它是否已经存在以避免重复。

Also we can decrease the duplication in the code: 我们也可以减少代码中的重复:

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

Maybe not the best solution (from running-time perspective), but it should work. 也许不是最佳的解决方案(从运行时的角度来看),但它应该可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM