2

My problem is slightly similar to: Sort an Array by keys based on another Array?

I have a nested associative array of file paths and directories, here is an example:

Array
(
    [Introduction] => /documentation/Introduction.md
    [Preface] => Array
        (
            [Installation] => /documentation/Preface/Installation.md
            [Requirements] => /documentation/Preface/Requirements.md
        )
)

If any value is an array, this represents a sub-directory, and if it's a string, it's a filepath. This is used to output a bulletpointed navigation list of documentation articles. The documentation articles are stored in markdown files.

THE PROBLEM:

The array is currently in alphabetical order. I want to store another array of filepaths and directories within the application containing the intended order, and I want a function to attempt to re-order the filepaths array above to match the order of the array stored in the application. If someone adds any new documentation articles to the file system, but doesn't add it to the order array, then that article needs to be placed at the bottom of the array for that directory.

So for example, if someone were to add a documentation article at /documentation/Preface/Release Notes.md, it would be added to the bottom of the Preface sub-array if it isn't specified in the order array. If it is specified in the order array, then it should appear wherever intended.

Community
  • 1
  • 1

2 Answers2

0

So basically you have a predefined nested array of files but you want to also include any files that exist but aren't in the predefined ordered array but exist in this other array.

If your ordered array is the same format as the first one then something like this should work.

function populateIfMissing( $arr1, $arr2 )
{
    foreach ( $arr1 as $key => $ele )
    {
        if ( is_array( $ele ) && in_array( $key, $arr1 ) )
        {
            // Directory exists
            populateIfMissing( $arr1[$key], $ ele );
        }
        elseif ( !in_array( $key, $arr1 ) )
        {
            //Not in array add it
            $arr1[$key] = $ele;
        }
    }
    return $arr1;
}

This is where $arr1 is the actual directory and $arr2 is the ordered structure.

The one problem with this is that files can be in $arr2 but not actually exist; but this should be relatively easy to check.

0

Thanks Conor. Finally got time to run through this and it works perfectly now. I used your code but had to make some changes:

function orderPaths($paths, $intended_order) {
    foreach ( $paths as $key => $ele )
    {
        if ( is_array( $ele ) && in_array( $key, $intended_order ) )
        {
            // Directory exists
        orderPaths( $paths[$key], $intended_order );
        }
        elseif ( !in_array( $paths[$key], $intended_order ) )
        {
            //Not in array add it
            $intended_order[$key] = $ele;
        }
    }
    return $intended_order;
}