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;

}

しかし、私は終わりになりません....誰かが助けてくれることを願っていますか?

4

3 に答える 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ループ内で自分自身を呼び出すことに注意してください。これは「再帰的アルゴリズム」と呼ばれます。

于 2013-02-05T16:10:50.317 に答える
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
)
*/
于 2013-02-05T16:19:55.793 に答える
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;

}
于 2013-02-05T16:19:35.090 に答える