PHP多维数组转换为扁平化文件夹视图

4

我有一个PHP中的多维数组,如下所示:

Array
(
    [folder1] => Array
        (
            [folder11] => Array
                (
                    [0] => index.html
                    [1] => tester.html
                )

            [folder12] => Array
                (
                    [folder21] => Array
                        (
                            [0] => astonmartindbs.jpg
                        )

                )

        )

)

应该将其转换为类似于这样的“文件路径”字符串:

Array
(
    [0] => 'folder1/folder11/index.html'
    [1] => 'folder1/folder11/tester.html'
    [2] => 'folder1/folder12/folder21/astonmartindbs.jpg'
)

有人有什么想法吗?

我尝试了很多次,但都失败了......这是我最后一次尝试的起点:

public function processArray( $_array ) {
foreach( $_array AS $key => $value ) {
    if( is_int( $key ) ) {

    } else {
    if( is_array( $value ) ) {
        $this->processArray( $value );
    } else {

    }
    }
}
echo $this->string;

}

但我还没有找到答案……希望有人能帮忙吗?
3个回答

5

你可能正在寻找一种递归函数。下面的函数可以起作用:

/**
 * Flattens the array from the question
 *
 * @param array  $a       Array or sub array of directory tree
 * @param string $prefix  Path prefix of $a
 */
function flatten($a, $prefix = './') {
    $paths = array();
    foreach($a as $index => $item) {
        // if item is a string then it is a file name (or a leaf in tree)
        // prefix it and add it to paths
        if(is_string($item)) {
            $paths []= $prefix . $item;
        } else {
            // if item is a directory we call flatten on it again.
            // also we append the new folder name to $prefix
            foreach(flatten($item, $prefix . $index . '/') as $path) {
                $paths []= $path;
            }
        }         
    }
    return $paths;
}

var_dump(flatten($a));

请注意,flatten() 在 foreach 循环中使用子数组作为参数调用自身。这被称为“递归算法”。

你的尝试看起来不错。似乎你只需要最后的诀窍 ;) - hek2mgl
是的,我也这么认为!但是尝试了大约两个小时后,我完全搞糊涂了。 - sunnysk32

2
如果你喜欢使用SPL,你可以使用RecursiveArrayIteratorRecursiveIteratorIterator来遍历一个扁平结构。我的结果将会是这样的:
$arr = array(); // your array
$arr = new RecursiveArrayIterator($arr);
$iterator = new RecursiveIteratorIterator($arr, RecursiveIteratorIterator::SELF_FIRST);


$currentDepth = 0;
$currentPath = array();
$result = array();

foreach($iterator as $key => $value) {
  // if depth is decreased
  if ($iterator->getDepth() < $currentDepth) {
    // pop out path values
    do {
      $currentDepth--;
      array_pop($currentPath);
    } while($iterator->getDepth() < $currentDepth);
  }

  if (is_array($value)) {
    // add parent to the path
    $currentPath[] = $key;
    $currentDepth++;
  } else {
    // add children to result array
    $result[] = implode('/', $currentPath).'/'.$value;
  }
}

转储数据的操作如下所示:
print_r($result);
/*
Array
(
    [0] => folder1/folder11/index.html
    [1] => folder1/folder11/tester.html
    [2] => folder1/folder12/folder21/astonmartindbs.jpg
)
*/

谢谢你!它像魔法一样运行,但我更喜欢@hek2mgl的答案! - sunnysk32

0
在您的情况下,您需要实现一个递归函数,您已经尝试过了,这里有一段简单的代码,可能会对您有所帮助,但我不确定它是否有效。
$result = array();
$d = 0;
$tmp = "";
public function processArray( $_array ,$before) {
foreach( $_array AS $key => $value ) {
    if( is_int( $key ) ) {  // If the key is a number, then there is no a sub-array 
      $result[$d] = $before . '/' . $value;
       $d++;
      $before="";
    } else {
    if( is_array( $value ) ) { // if the value is an array, then we will add the key into string that we will return and search into subarray.
 $before = $before . '/' . $key;
        $this->processArray( $value,$before  );
    } else {


    }
    }
}
return $result;

}

谢谢你。但是我选择了@hek2mgl的答案。 - sunnysk32

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接