PHP中多维数组的迭代

PHP中多维数组的迭代,php,arrays,multidimensional-array,Php,Arrays,Multidimensional Array,在过去的几天里,我一直在思考如何在多维数组中处理对键的迭代,但我就是想不出来。问题是,我不知道数组有多深——我希望我的代码能够处理任何深度的数组 数组本身来自高级自定义字段,但这并不太重要。我需要迭代数组,在每个数组键上运行一个以字段开头的函数(将其从字段*转换为其专有名称,如post\u title或其他内容),然后用相同的结构和值重建数组(尽管顺序并不重要)。该数组如下所示: array (size=12) 'field_5b23d04fef8a6' => string '' (l

在过去的几天里,我一直在思考如何在多维数组中处理对键的迭代,但我就是想不出来。问题是,我不知道数组有多深——我希望我的代码能够处理任何深度的数组

数组本身来自高级自定义字段,但这并不太重要。我需要迭代数组,在每个数组键上运行一个以
字段
开头的函数(将其从
字段*
转换为其专有名称,如
post\u title
或其他内容),然后用相同的结构和值重建数组(尽管顺序并不重要)。该数组如下所示:

array (size=12)
  'field_5b23d04fef8a6' => string '' (length=0)
  'field_5b23d04fefa99' => string '' (length=0)
  'field_5b23d04fefe85' => string '' (length=0)
  'field_5b23d04ff0077' => string '' (length=0)
  'field_5b23d04ff026c' => string '' (length=0)
  'field_5b23d0bdb3c1a' => string 'Version 1' (length=9)
  'field_5b23d0f48538b' => string '' (length=0)
  'field_5b23d0f485772' => string '' (length=0)
  'field_5b23d0d52be2d' => string '' (length=0)
  'field_5b5ed10a6a7bc' => string '' (length=0)
  'field_5b5ed10a6bcf5' => 
    array (size=1)
      0 => 
        array (size=1)
          'field_5b5ed10acd264' => 
            array (size=1)
              0 => 
                array (size=6)
                  'field_5b5ed10b0c9ca' => string '0' (length=1)
                  'field_5b5ed10b0cce2' => string 'TEST1234' (length=8)
                  'field_5b5ed10b0d0fd' => string 'Download title' (length=14)
                  'field_5b5ed10b0d4e2' => string 'EN' (length=2)
                  'field_5b5ed10b0d72e' => string 'A00' (length=3)
                  'field_5b5ed10b0df27' => string '887' (length=3)
  'field_5b23d088500a4' => string '' (length=0)
$arr = [
    'a',
    'b',
    'c',
    [
        'd',
        'e',
        'f',
        [
            'g',
            'h',
            'i',
        ],
    ],
];

class MyIterator
{
    public function iterate( $array )
    {
        foreach ( $array as $a ) {
            if ( is_array( $a ) ) {
                $this->iterate($a);
            } else {
                echo $a;
            }
        }
    }
}

$iterator = new MyIterator();

$iterator->iterate($arr);
$input = array(
    'field_5b23d04fef8a6' => '',
    'field_5b23d04fefa99' => '',
    'field_5b23d04fefe85' => '',
    'field_5b23d04ff0077' => '',
    'field_5b23d04ff026c' => '',
    'field_5b23d0bdb3c1a' => 'Version 1',
    'field_5b23d0f48538b' => '',
    'field_5b23d0f485772' => '',
    'field_5b23d0d52be2d' => '',
    'field_5b5ed10a6a7bc' => '',
    'field_5b5ed10a6bcf5' => array(
        array(
            'field_5b5ed10acd264' => array(
                array(
                    'field_5b5ed10b0c9ca' => '0',
                    'field_5b5ed10b0cce2' => 'TEST1234',
                    'field_5b5ed10b0d0fd' => 'Download title',
                    'field_5b5ed10b0d4e2' => 'EN',
                    'field_5b5ed10b0d72e' => 'A00',
                    'field_5b5ed10b0df27' => '887',
                ),
            ),
        ),
    ),
    'field_5b23d088500a4' => '',
);


// recursively re-key array
function dostuff($input){
    // always refer to self, even if you rename the function
    $thisfunction = __function__;
    $output = array();
    foreach($input as $key => $value){
        // change key
        $newkey = (is_string($key) ? preg_replace('/^field_/', 'post_title_', $key) : $key);
        // iterate on arrays
        if(is_array($value)){
            $value = $thisfunction($value);
        }
        $output[$newkey] = $value;
    }
    return $output;
}

var_dump(dostuff($input));

处理这个问题的最佳方法是什么?我已经看过递归函数和ResursiveArrayIterator,但我发现的示例中没有一个足够接近我的需求。

您可以这样做:

array (size=12)
  'field_5b23d04fef8a6' => string '' (length=0)
  'field_5b23d04fefa99' => string '' (length=0)
  'field_5b23d04fefe85' => string '' (length=0)
  'field_5b23d04ff0077' => string '' (length=0)
  'field_5b23d04ff026c' => string '' (length=0)
  'field_5b23d0bdb3c1a' => string 'Version 1' (length=9)
  'field_5b23d0f48538b' => string '' (length=0)
  'field_5b23d0f485772' => string '' (length=0)
  'field_5b23d0d52be2d' => string '' (length=0)
  'field_5b5ed10a6a7bc' => string '' (length=0)
  'field_5b5ed10a6bcf5' => 
    array (size=1)
      0 => 
        array (size=1)
          'field_5b5ed10acd264' => 
            array (size=1)
              0 => 
                array (size=6)
                  'field_5b5ed10b0c9ca' => string '0' (length=1)
                  'field_5b5ed10b0cce2' => string 'TEST1234' (length=8)
                  'field_5b5ed10b0d0fd' => string 'Download title' (length=14)
                  'field_5b5ed10b0d4e2' => string 'EN' (length=2)
                  'field_5b5ed10b0d72e' => string 'A00' (length=3)
                  'field_5b5ed10b0df27' => string '887' (length=3)
  'field_5b23d088500a4' => string '' (length=0)
$arr = [
    'a',
    'b',
    'c',
    [
        'd',
        'e',
        'f',
        [
            'g',
            'h',
            'i',
        ],
    ],
];

class MyIterator
{
    public function iterate( $array )
    {
        foreach ( $array as $a ) {
            if ( is_array( $a ) ) {
                $this->iterate($a);
            } else {
                echo $a;
            }
        }
    }
}

$iterator = new MyIterator();

$iterator->iterate($arr);
$input = array(
    'field_5b23d04fef8a6' => '',
    'field_5b23d04fefa99' => '',
    'field_5b23d04fefe85' => '',
    'field_5b23d04ff0077' => '',
    'field_5b23d04ff026c' => '',
    'field_5b23d0bdb3c1a' => 'Version 1',
    'field_5b23d0f48538b' => '',
    'field_5b23d0f485772' => '',
    'field_5b23d0d52be2d' => '',
    'field_5b5ed10a6a7bc' => '',
    'field_5b5ed10a6bcf5' => array(
        array(
            'field_5b5ed10acd264' => array(
                array(
                    'field_5b5ed10b0c9ca' => '0',
                    'field_5b5ed10b0cce2' => 'TEST1234',
                    'field_5b5ed10b0d0fd' => 'Download title',
                    'field_5b5ed10b0d4e2' => 'EN',
                    'field_5b5ed10b0d72e' => 'A00',
                    'field_5b5ed10b0df27' => '887',
                ),
            ),
        ),
    ),
    'field_5b23d088500a4' => '',
);


// recursively re-key array
function dostuff($input){
    // always refer to self, even if you rename the function
    $thisfunction = __function__;
    $output = array();
    foreach($input as $key => $value){
        // change key
        $newkey = (is_string($key) ? preg_replace('/^field_/', 'post_title_', $key) : $key);
        // iterate on arrays
        if(is_array($value)){
            $value = $thisfunction($value);
        }
        $output[$newkey] = $value;
    }
    return $output;
}

var_dump(dostuff($input));
它打印这个:

abcdefghi

您可以像这样递归地遍历数组

function recursiveWalk($array, callable $x)
{
    $result = [];
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $result[$key] = recursiveWalk($value, $x);
        } else {
            $result[$key] = $x($value);
        }
    }
    return $result;
}
例如:

$array = [
    "aaa" => 1,
    "sub1" => [
        "xxx" => 2,
        "sub2" => [
            "yyy" => 3,
            "ttt" => 4
        ]
    ]
];
print_r(recursiveWalk($array, function ($x) {
    return $x + 1;
}));

Array
(
    [aaa] => 2
    [sub1] => Array
        (
            [xxx] => 3
            [sub2] => Array
                (
                    [yyy] => 4
                    [ttt] => 5
                )

        )

)

如果找到如下嵌套数组,则可以递归调用相同的函数:

array (size=12)
  'field_5b23d04fef8a6' => string '' (length=0)
  'field_5b23d04fefa99' => string '' (length=0)
  'field_5b23d04fefe85' => string '' (length=0)
  'field_5b23d04ff0077' => string '' (length=0)
  'field_5b23d04ff026c' => string '' (length=0)
  'field_5b23d0bdb3c1a' => string 'Version 1' (length=9)
  'field_5b23d0f48538b' => string '' (length=0)
  'field_5b23d0f485772' => string '' (length=0)
  'field_5b23d0d52be2d' => string '' (length=0)
  'field_5b5ed10a6a7bc' => string '' (length=0)
  'field_5b5ed10a6bcf5' => 
    array (size=1)
      0 => 
        array (size=1)
          'field_5b5ed10acd264' => 
            array (size=1)
              0 => 
                array (size=6)
                  'field_5b5ed10b0c9ca' => string '0' (length=1)
                  'field_5b5ed10b0cce2' => string 'TEST1234' (length=8)
                  'field_5b5ed10b0d0fd' => string 'Download title' (length=14)
                  'field_5b5ed10b0d4e2' => string 'EN' (length=2)
                  'field_5b5ed10b0d72e' => string 'A00' (length=3)
                  'field_5b5ed10b0df27' => string '887' (length=3)
  'field_5b23d088500a4' => string '' (length=0)
$arr = [
    'a',
    'b',
    'c',
    [
        'd',
        'e',
        'f',
        [
            'g',
            'h',
            'i',
        ],
    ],
];

class MyIterator
{
    public function iterate( $array )
    {
        foreach ( $array as $a ) {
            if ( is_array( $a ) ) {
                $this->iterate($a);
            } else {
                echo $a;
            }
        }
    }
}

$iterator = new MyIterator();

$iterator->iterate($arr);
$input = array(
    'field_5b23d04fef8a6' => '',
    'field_5b23d04fefa99' => '',
    'field_5b23d04fefe85' => '',
    'field_5b23d04ff0077' => '',
    'field_5b23d04ff026c' => '',
    'field_5b23d0bdb3c1a' => 'Version 1',
    'field_5b23d0f48538b' => '',
    'field_5b23d0f485772' => '',
    'field_5b23d0d52be2d' => '',
    'field_5b5ed10a6a7bc' => '',
    'field_5b5ed10a6bcf5' => array(
        array(
            'field_5b5ed10acd264' => array(
                array(
                    'field_5b5ed10b0c9ca' => '0',
                    'field_5b5ed10b0cce2' => 'TEST1234',
                    'field_5b5ed10b0d0fd' => 'Download title',
                    'field_5b5ed10b0d4e2' => 'EN',
                    'field_5b5ed10b0d72e' => 'A00',
                    'field_5b5ed10b0df27' => '887',
                ),
            ),
        ),
    ),
    'field_5b23d088500a4' => '',
);


// recursively re-key array
function dostuff($input){
    // always refer to self, even if you rename the function
    $thisfunction = __function__;
    $output = array();
    foreach($input as $key => $value){
        // change key
        $newkey = (is_string($key) ? preg_replace('/^field_/', 'post_title_', $key) : $key);
        // iterate on arrays
        if(is_array($value)){
            $value = $thisfunction($value);
        }
        $output[$newkey] = $value;
    }
    return $output;
}

var_dump(dostuff($input));
所以我一直在看这个,据我所知,没有用于递归的包装函数,所以它是:

// general function for recursively doing something
// $input -> array() / the array you wan to process
// $valuefunction -> callable | null / function to run on all values *
// $keyfunction -> callable | null / function to run on all keys *
//   * at least one has to defined or there is nothing to do
//   callable has two inputs
//     $input -> current branch
//     $depth -> (int) how deep in the structure are we
//   i.e: recursion($some_array, function($branch, $depth){something..}, 'trim');
function recursion($input, $valuefunction = false, $keyfunction = false){
    if(!is_array($input)){
        trigger_error('Input is '.gettype($input).'. Array expected', E_USER_ERROR);
        return null;
    }
    if(!is_callable($valuefunction)){$valuefunction = false;}
    if(!is_callable($keyfunction)){$keyfunction = false;}
    if(!$valuefunction && !$keyfunction){
        trigger_error('Input is unchanged!', E_USER_WARNING);
        return $input;
    }
    // use recursion internally, so I can pass stuff by reference
    // and do the above checks only once.
    $recurse = function(&$branch, $depth = 0) use (&$recurse, &$valuefunction, &$keyfunction){
        $output = array();
        foreach($branch as $key => $value){
            $key = $keyfunction ? $keyfunction($key, $depth) : $key;
            $output[$key] = (is_array($value) ?
                $recurse($value, $depth + 1) :
                ($valuefunction ?
                    $valuefunction($value, $depth) :
                    $value
                )
            );
        }
        return $output;
    };
    return $recurse($input);
}

$valuefunction = function($value, $depth){
    return is_string($value) ? $depth.'_'.$value : $value;
};
function keyfunction($key){
    return is_string($key) ? preg_replace('/^field_/', 'post_title_', $key) : $key;
}

var_dump(recursion($input, $valuefunction, 'keyfunction'));
或者举个例子:

var_dump(recursion($input, 0, function($key){
    return is_string($key) ? preg_replace('/^field_/', 'post_title_', $key) : $key;
}));

你能把你期望的结果加在一起吗!改变钥匙是我无法理解的。谢谢:)