PHP foreach multi-dimensional array traversal implementation method, foreach multi-dimensional
Introduction
Normally, our foreach can print each key => value in a one-dimensional array in order, but if it is a multi-dimensional array, it needs to loop in a nested loop, or Recursive Implementation, however, these methods are not flexible enough, because it is impossible to create endless nested loops without knowing how many dimensions the array is. If recursive expressions are used, but how can I implement it if I only want to use foreach to loop it all out?
Method 1
RecursiveIteratorIterator
$ Test_arr = array (, 3, array (4, 'A' => 5, 6, array (7, 'bb '=> 8 ); $ arrayiter = new RecursiveArrayIterator ($ test_arr); $ iteriter = new RecursiveIteratorIterator ($ arrayiter ); // print it directly to print the foreach ($ iteriter as $ key => $ val) {echo $ key. '=> '. $ val ;} // result/* 0 => 1 1 => 2 2 => 3 0 => 4 aa => 5 2 => 6 0 => 7 bb => 8 4 => 9 5 => 10 4 => 11 5 => 12 */
Implementation Method 2
Implement an iterator class similar to RecursiveIteratorIterator to implement the multi-dimensional array horizontal printing function.
Class foreachPrintfArr implements Iterator {// current array scope private $ _ items; private $ _ old_items; // save each execution of the array environment stack private $ _ stack = array (); public function _ construct ($ data = array () {$ this-> _ items = $ data;} private function _ isset () {$ val = current ($ this-> _ items); if (empty ($ this-> _ stack )&&! $ Val) {return false;} else {return true;} public function current () {$ this-> _ old_items = null; $ val = current ($ this-> _ items); // if it is an array, save the current execution environment and switch to the new array execution environment if (is_array ($ val )) {array_push ($ this-> _ stack, $ this-> _ items); $ this-> _ items = $ val; return $ this-> current ();} // determine whether to switch back to the last execution environment after the current execution is complete // (1) if the execution exists and continues // (2) if the execution does not exist and the Environment stack is empty, it indicates that the current execution is to the last element // (3) if the next element in the current array environment does not exist, save the current execution array environment $ this-> _ old_ite MS = $ this-> _ items; // then switch the last execution environment $ this-> _ items = array_pop ($ this-> _ stack) to continue the loop, until the next // element in the current array environment is not empty while (1) {if (next ($ this-> _ items) {prev ($ this-> _ items ); break;} elseif (empty ($ this-> _ stack) {end ($ this-> _ items); break ;} else {end ($ this-> _ items); if (! $ This-> _ old_items) $ this-> _ old_items = $ this-> _ items; $ this-> _ items = array_pop ($ this-> _ stack );}} return $ val;} public function next () {next ($ this-> _ items);} public function key () {// because the key () function is executed in current () after the function // switch the execution environment in the current () function, the last key in the previous execution environment will become the key after the switch, so $ this-> _ old_items Save the execution environment before switching // prevent key printing error return $ this-> _ old_items? Key ($ this-> _ old_items): key ($ this-> _ items);} public function rewind () {reset ($ this-> _ items );} public function valid () {return $ this-> _ isset ();}}
Internal Execution Mode
1. foreach loop our custom foreachPrintfArr class will automatically call the five internal methods valid (), rewind (), key (), next (), current () we only need to implement these methods.
2. Call sequence:
1st times => rewind-> valid-> current-> key
2nd times ~ N times => next-> valid-> current-> key
$ Test_arr = array (, 3, array (4, 'A' => 5, 6, array (7, 'bb '=> 8 ); $ iteriter = new foreachPrintfArr ($ test_arr); foreach ($ iteriter as $ key => $ val) {echo $ key. '=> '. $ val;} // result: /* 0 => 1 1 => 2 2 => 3 0 => 4 aa => 5 2 => 6 0 => 7 bb => 8 4 => 9 5 => 10 4 => 11 5 => 12 */
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.