Search code examples
phparraysmultidimensional-arraykey

Array elements lose their keys after calling array_values()


I am having an issue getting the inner array key/value pairs correctly. I have the outer array correct but the inner arrays just have index numbers as keys instead of me setting the key to what I am wanting. Seems like I'm missing a step in the formation of the inner array but I'm not sure what it is.

My current code now:

$path = './downloads/Current/v5.5/';
$blacklist = array('orig55205Web', 'SQL Files', '.', '..');

foreach (new DirectoryIterator($path) as $folder) {
    if($folder->isDot() || in_array($folder, $blacklist)) continue;

    if($folder->isDir()) {
        $item = $folder->getFilename();
        $versions[$item] = array();
        
        if ($handle = opendir($path . $item)) {
            while (false !== ($file = readdir($handle))) {
                if (!in_array($file, $blacklist)) {
                    array_push($versions[$item], $file);
                }
                asort($versions[$item]);
                $versions[$item] = array_values($versions[$item]);
            }
        }
        closedir($handle);
    }
}
ksort($versions);
print_r($versions);

My output looks like this currently:

Array
(
    [55106Web] => Array
        (
            [0] => 55106.txt
            [1] => ClientSetup.exe
            [2] => ClientSetup32.exe
            [3] => Setup.exe
            [4] => Setup32.exe
        )

    [55122Web] => Array
        (
            [0] => 55122.txt
            [1] => ClientSetup.exe
            [2] => ClientSetup32.exe
            [3] => Setup.exe
            [4] => Setup32.exe
        )
 )

What i WANT it to output:

Array
(
    [55106Web] => Array
        (
            [Version] => 55106.txt
            [CS64] => ClientSetup.exe
            [CS32] => ClientSetup32.exe
            [S64] => Setup.exe
            [S32] => Setup32.exe
        )

    [55122Web] => Array
        (
            [Version] => 55122.txt
            [CS64] => ClientSetup.exe
            [CS32] => ClientSetup32.exe
            [S64] => Setup.exe
            [S32] => Setup32.exe
        )
 )

Solution

  • There are two issues here. First, you're not doing anything that assigns string-based indexes to the inner array.

    Second, even if you were, those indexes would be removed as a result of your use of array_values From the docs array_values() returns all the values from the array and indexes the array numerically.

    So you should assign the indexes (see below), and remove the call to array_values.

    This may not exactly suit your needs 100%, but should get you going in the right direction.

    $indexesArray = array("Version", "CS64", "CS32", "S64", "S32");
    $i = 0;
    while (false !== ($file = readdir($handle))) {
        if (!in_array($file, $blacklist)) {
            $versions[$item][$indexesArray[$i]] = $file;
            $i++
        }
    }
    asort($versions[$item]);