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;
}));
你能把你期望的结果加在一起吗!改变钥匙是我无法理解的。谢谢:)