PHP array advanced traversal and operation methods

Source: Internet
Author: User
Tags foreach arrays data structures php and require

PHP's processing of arrays can be called one of the most attractive features of the language. It supports more than 70 array-related functions. Whether you want to flip an array, determine whether a value exists in the array, convert the array into a string, or calculate the size of the array, you can simply execute an existing function. However, there are also some array-related tasks that require developers to be more demanding. It is only known that the manual has a function that cannot be solved, these tasks require a deep understanding of the original features of PHP and the imagination to solve the problem.

Multi-dimensional join array sorting
PHP provides some array sorting functions, such as sort (), ksort (), and asort (), but does not provide sorting for multi-dimensional joined arrays.


For example, the following array:

Array
(
[0] => Array
    (
[Name] => chess
[Price] = & gt; 12.99
    )

[1] => Array
    (
[Name] => checkers
[Price] = & gt; 9.99
    )

[2] => Array
    (
[Name] => backgammon
[Price] = & gt; 29.99
    )
)

To sort the array in ascending order, you need to write a function to compare the price, and then pass the function as a callback function to the usort () function to implement this function:

The code is as follows: Copy code

Function comparePrice ($ priceA, $ priceB ){
Return $ priceA ['price']-$ priceB ['price'];
}

Usort ($ games, 'companyprice ');

After the program fragment is executed, the array is sorted. The result is as follows:

Array
(
[0] => Array
    (
[Name] => checkers
[Price] = & gt; 9.99
    )

[1] => Array
    (
[Name] => chess
[Price] = & gt; 12.99
    )

[2] => Array
    (
[Name] => backgammon
[Price] = & gt; 29.99
    )
)

Sort the array in descending order and change the positions of the two subtraction values in the comparePrice () function.

Traverse arrays in reverse order
PHP's While loop and For loop are the most common methods to traverse an array. But how do you traverse the following array?

Array
(
[0] => Array
    (
[Name] => Board
[Games] => Array
        (
[0] => Array
            (
[Name] => chess
[Price] = & gt; 12.99
            )

[1] => Array
            (
[Name] => checkers
[Price] = & gt; 9.99
            )
        )
    )
)

The PHP Standard Library has an iterators class for the set, which is not only used to traverse some heterogeneous data structures (such as file systems and database query result sets ), you can also traverse nested arrays with unknown sizes. For example, you can use the RecursiveArrayIterator iterator to traverse the preceding array:

The code is as follows: Copy code

$ Iterator = new RecursiveArrayIterator ($ games );
Iterator_apply ($ iterator, 'navigateearray', array ($ iterator ));

Function navigateArray ($ iterator ){
While ($ iterator-> valid ()){
If ($ iterator-> hasChildren ()){
NavigateArray ($ iterator-> getChildren ());
} Else {
Printf ("% s: % s", $ iterator-> key (), $ iterator-> current ());
  }
$ Iterator-> next ();
 } 
}

The following result is displayed when the code is executed:

Name: Board
Name: chess
Price: 12.99
Name: checkers
Price: 9.99

Filter join array results
Suppose you get an array like the next one, but you just want to operate the element with a price lower than $11.99:

Array
(
[0] => Array
    (
[Name] => checkers
[Price] = & gt; 9.99
    )

[1] => Array
    (
[Name] => chess
[Price] = & gt; 12.99
    )

[2] => Array
    (
[Name] => backgammon
[Price] = & gt; 29.99
    )
)

Using the array_reduce () function can be easily implemented:

The code is as follows: Copy code

Function filterGames ($ game ){
Return ($ game ['price'] <11.99 );
}

$ Names = array_filter ($ games, 'filtergames ');

The array_reduce () function filters out all elements that do not meet the callback function. In this example, the callback function is filterGames. Any element with a price lower than 11.99 will be left behind, and others will be removed. Execution result of the code segment:

Array
(
[1] => Array
    (
[Name] => checkers
[Price] = & gt; 9.99
    )
)

Convert objects into arrays
One requirement is to convert an object into an array. The method is much simpler than you think. Only forced conversion is enough! Example:

The code is as follows: Copy code

Class Game {
Public $ name;
Public $ price;
}

$ Game = new Game ();
$ Game-> name = 'Chess ';
$ Game-> price = 12.99;

Print_r (array ($ game ));

The following results are generated when you execute this example:

Array
(
[0] => Game Object
  (
[Name] => chess
[Price] = & gt; 12.99
  )
)

Converting an object into an array may lead to unpredictable side effects. For example, in the code snippet above, all member variables are of the public type, but the returned results for private variables are different. The following is another example:

The code is as follows: Copy code

Class Game {
Public $ name;
Private $ _ price;

Public function setPrice ($ price ){
$ This-> _ price = $ price;
 }
}

$ Game = new Game ();
$ Game-> name = 'Chess ';
$ Game-> setPrice (12.99 );

Print_r (array ($ game); execute this code snippet:

Array
(
[0] => Game Object
  (
[Name] => chess
[_ Price: Game: private] = & gt; 12.99
  )
)

As you can see, for differentiation, the key of the private variable stored in the array is automatically changed.

"Natural sorting" of arrays"
PHP is not sure about the sorting result of the "letter and digit" string. For example, assume that you have many image names stored in the array:

The code is as follows: Copy code

$ Arr = array (
0 => 'madden2011.png ',
1 => 'madden2011-1.png ',
2 => 'madden2011-2.png ',
3 => 'madden2012.png'
);

How do you sort the array? If you use sort () to sort the array, the result is as follows:

Array
(
Madden2011-1.png
Madden2011-2.png
[2] => madden2011.png
[3] => madden2012.png
)

Sometimes this is what we want, but what should we do if we want to keep the original subscript? To solve this problem, you can use the natsort () function, which sorts arrays in a natural way:

The code is as follows: Copy code

<? Php
$ Arr = array (
0 => 'madden2011.png ',
1 => 'madden2011-1.png ',
2 => 'madden2011-2.png ',
3 => 'madden2012.png'
);

Natsort ($ arr );
Echo "<pre>"; print_r ($ arr); echo "</pre> ";
?>

Running result:

Array
(
Madden2011-1.png
Madden2011-2.png
[0] => madden2011.png
[3] => madden2012.png
)

Change value during traversal
Reference operator &
Let's take a look at the $ array in the following code. In The foreach loop, we use the reference operator for $ value, so that when we modify the value of $ value in the loop, then, the corresponding element value in $ array is modified.

The code is as follows: Copy code

<? Php
$ Array = array ("A" => 1, "B" => 1, "C" => 1, "D" => 1 );
Foreach ($ array as & amp; $ value)
$ Value = 2;
Print_r ($ array );
?>

The output of the code above is as follows:

Array ([A] => 2 [B] => 2 [C] => 2 [D] => 2)
As you can see, the values of each key in $ array are changed to 2. It seems that this method does work.

Operate array elements with key values
Sometimes, the array may indicate some correlated elements. If one of these correlated elements is encountered, the other elements are marked, the above reference is definitely useless. When modifying these associated elements, you need to use the corresponding key value. Try it first:

The code is as follows: Copy code

<? Php
$ Array = array ("A" => 1, "B" => 1, "C" => 1, "D" => 1 );
Foreach ($ array as $ key => $ value ){
If ($ key = "B "){
$ Array ["A"] = "CHANGE ";
$ Array ["D"] = "CHANGE ";
Print_r ($ array );
Echo '<br/> ';
    }
 
If ($ value = "CHANGE ")
Echo $ value. '<br/> ';
}
Print_r ($ array );
?>

Don't worry about output. What should we think? Print the modified array, print a "CHANGE", and print the modified array again. Right? Let's take a look at the output!

Array ([A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE)
Array ([A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE)
Why? What is the situation? Where is our CHANGE?

According to our idea, since $ array has changed, the new value "CHANGE" should be output when the elements whose key value is D are traversed! But it is not what we think. What did PHP do here? Modify the above code slightly. Since "D" => CHANGE is correct when the array is printed, we can modify the judgment condition of the second if statement:

The code is as follows: Copy code

<? Php
$ Array = array ("A" => 1, "B" => 1, "C" => 1, "D" => 1 );
Foreach ($ array as $ key => $ value ){
If ($ key = "B "){
$ Array ["A"] = "CHANGE ";
$ Array ["D"] = "CHANGE ";
Print_r ($ array );
Echo '<br/> ';
    }
   
If ($ array [$ key] === "CHANGE ")
Echo $ value. '<br/> ';
}
Print_r ($ array );
?>

Guess what it will output? $ Value is definitely not equal to "CHANGE! Is it equal to 1?

The code is as follows: Copy code
Array ([A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE)
1
Array ([A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE)

So, it is indeed 1.

What is the reason for this? Go to the foreach page of the PHP document:

Note: Unless the array is referenced, foreach operates on a copy of the specified array, rather than the array itself. Foreach has some side effects on array pointers. Do not depend on the value of the array pointer in a foreach loop or after a loop unless it is reset.

Previously, foreach operated on a copy of the specified array. No wonder, $ value is useless! The above problem is solved. In foreach, you only need to perform various assignment operations based on the elements in the $ array key.


Summary and extension
PHP's array traversal and operation capabilities are indeed very powerful, but the solution to some slightly complicated problems is not so obvious. In fact, this is true in any field. A language and syntax provide basic operations, and developers must think, imagine, and write code to solve complicated problems.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.