65
91
Sorting Multidimensional Arrays
Using asort() and ksort() to Sort Arrays
If you are using an array with descriptive keys to store items and their prices,you need to
use different kinds of sort functions to keep keys and values together as they are sorted.
The following code creates an array containing the three products and their associated
prices and then sorts the array into ascending price order:
$prices = array( ‘Tires’=>100, ‘Oil’=>10, ‘Spark Plugs’=>4 );
asort($prices);
The function
asort()
orders the array according to the value of each element. In the
array,the values are the prices,and the keys are the textual descriptions.If,instead of
sorting by price,you want to sort by description,you can use
ksort()
,which sorts by
key rather than value.The following code results in the keys of the array being ordered
alphabetically—
Oil
,
Spark Plugs
,
Tires:
$prices = array( ‘Tires’=>100, ‘Oil’=>10, ‘Spark Plugs’=>4 );
ksort($prices);
Sorting in Reverse
The three different sorting functions—
sort()
,
asort()
,and
ksort()
—sort an array
into ascending order. Each function has a matching reverse sort function to sort an array
into descending order.The reverse versions are called
rsort()
,
arsort()
,and
krsort()
.
You use the reverse sort functions in the same way you use the ascending sort func-
tions.The
rsort()
function sorts a single-dimensional numerically indexed array into
descending order.The
arsort()
function sorts a one-dimensional array into descending
order using the value of each element.The
krsort()
function sorts a one-dimensional
array into descending order using the key of each element.
Sorting Multidimensional Arrays
Sorting arrays with more than one dimension,or by something other than alphabetical
or numerical order,is more complicated. PHP knows how to compare two numbers or
two text strings, but in a multidimensional array, each element is an array.PHP does not
know how to compare two arrays,so you need to create a method to compare them.
Most of the time,the order of the words or numbers is fairly obvious,but for complicat-
ed objects, it becomes more problematic.
User-Defined Sorts
The following is the definition of a two-dimensional array used earlier.This array stores
Bob’s three products with a code,a description,and a price for each:
$products = array( array( ‘TIR’, ‘Tires’, 100 ),
array( ‘OIL’, ‘Oil’, 10 ),
array( ‘SPK’, ‘Spark Plugs’, 4 ) );
107
92
Chapter 3 Using Arrays
If you sort this array, in what order will the values appear? Because you know what the
contents represent,there are at least two useful orders.You might want the products sort-
ed into alphabetical order using the description or by numeric order by the price. Either
result is possible,but you need to use the function
usort()
and tell PHP how to com-
pare the items.To do this, you need to write your own comparison function.
The following code sorts this array into alphabetical order using the second column
in the array—the description:
function compare($x, $y)
{
if ( $x[1] == $y[1] )
return 0;
else if ( $x[1] < $y[1] )
return -1;
else
return 1;
}
usort($products, ‘compare’);
So far in this book,you have called a number of the built-in PHP functions.To sort this
array,you need to define a function of your own.We examine writing functions in detail
in Chapter 5,“Reusing Code and Writing Functions,” but here is a brief introduction.
You define a function by using the keyword
function
.You need to give the function
a name.Names should be meaningful,so you can call it
compare()
for this example.
Many functions take parameters or arguments.This
compare()
function takes two:one
called
$x
and one called
$y
.The purpose of this function is to take two values and deter-
mine their order.
For this example,the
$x
and
$y
parameters are two of the arrays within the main
array,each representing one product.To access the
Description
of the array
$x
,you
type
$x[1]
because the
Description
is the second element in these arrays, and number-
ing starts at zero.You use
$x[1]
and
$y[1]
to compare each
Description
from the
arrays passed into the function.
When a function ends,it can give a reply to the code that called it.This process is
called returning a value.To return a value,you use the keyword
return
in the function.
For example,the line
return 1;
sends the value
1
back to the code that called the
function.
To be used by
usort()
,the
compare()
function must compare
$x
and
$y
.The func-
tion must return
0
if
$x
equals
$y
,a negative number if it is less, or a positive number if
it is greater.The function will return
0
,
1
,or
-1
,depending on the values of
$x
and
$y
.
The final line of code calls the built-in function
usort()
with the array you want
sorted (
$products
) and the name of the comparison function (
compare()
).
89
93
Sorting Multidimensional Arrays
If you want the array sorted into another order,you can simply write a different
comparison function.To sort by price,you need to look at the third column in the array
and create this comparison function:
function compare($x, $y)
{
if ( $x[2] == $y[2] )
return 0;
else if ( $x[2] < $y[2] )
return -1;
else
return 1;
}
When
usort($products, ‘compare’)
is called, the array is placed in ascending order
by price.
The u in
usort()
stands for user because this function requires a user-defined com-
parison function.The
uasort()
and
uksort()
versions of
asort
and
ksort
also require
user-defined comparison functions.
Similar to
asort()
,
uasort()
should be used when sorting a non-numerically
indexed array by value.Use
asort
if your values are simple numbers or text.Define a
comparison function and use
uasort()
if your values are more complicated objects such
as arrays.
Similar to
ksort()
,
uksort()
should be used when sorting a non-numerically
indexed array by key.Use
ksort
if your keys are simple numbers or text.Define a com-
parison function and use
uksort()
if your keys are more complicated objects such as
arrays.
Reverse User Sorts
The functions
sort()
,
asort()
,and
ksort()
all have a matching reverse sorts with an r
in the function name.The user-defined sorts do not have reverse variants,but you can
sort a multidimensional array into reverse order.Because you provide the comparison
function,you can write a comparison function that returns the opposite values.To sort
into reverse order,the function needs to return
1
if
$x
is less than
$y
and
-1
if
$x
is
greater than
$y
.For example,
function reverse_compare($x, $y)
{
if ( $x[2] == $y[2] )
return 0;
else if ( $x[2] < $y[2] )
return 1;
else
return -1;
}
46
94
Chapter 3 Using Arrays
Calling
usort($products, ‘reverse_compare’)
would now result in the array being
placed in descending order by price.
Reordering Arrays
For some applications,you might want to manipulate the order of the array in other
ways.The function
shuffle()
randomly reorders the elements of your array.The func-
tion
array_reverse()
gives you a copy of your array with all the elements in reverse
order.
Using shuffle()
Bob wants to feature a small number of his products on the front page of his site.He has
a large number of products but would like three randomly selected items shown on the
front page. So that repeat visitors do not get bored,he would like the three chosen prod-
ucts to be different for each visit.He can easily accomplish his goal if all his products are
in an array. Listing 3.1 displays three randomly chosen pictures by shuffling the array into
a random order and then displaying the first three.
Listing 3.1 bobs_front_page.php—Using PHP to Produce a Dynamic Front Page
for Bob’s Auto Parts
<?php
$pictures = array(‘tire.jpg’, ‘oil.jpg’, ‘spark_plug.jpg’,
‘door.jpg’, ‘steering_wheel.jpg’,
‘thermostat.jpg’, ‘wiper_blade.jpg’,
‘gasket.jpg’, ‘brake_pad.jpg’);
shuffle($pictures);
?>
<html>
<head>
<title>Bob’s Auto Parts</title>
</head>
<body>
<center>
<h1>Bob’s Auto Parts</h1>
<table width = ‘100%’>
<tr>
<?php
for ( $i = 0; $i < 3; $i++ )
{
echo ‘<td align=”center”><img src=”’;
echo $pictures[$i];
echo ‘“ width=”100” height=”100”></td>’;
33
95
Reordering Arrays
}
?>
</tr>
</table>
</center>
</body>
</html>
Because the code selects random pictures,it produces a different page nearly every time
you load it,as shown in Figure 3.5.
Figure 3.5 The
shuffle()
function enables you to feature three randomly
chosen products.
In older versions of PHP,the
shuffle()
function required that you seed the random
number generator first by calling
srand()
.This step is no longer required.
The
shuffle()
function has not had a very illustrious history.In older versions of
PHP,it did not shuffle very well,giving a result that was not very random.In version
4.2.x on Windows,for instance,it did not shuffle at all,giving a result that was exactly
what you started with.In version 5,it seems to work.If this function is important to
you,test it on your server before employing it in your applications.
Because you do not really need the whole array reordered,you can achieve the same
result using the function
array_rand()
.
Listing 3.1 Continued
66
96
Chapter 3 Using Arrays
Using array_reverse()
The function
array_reverse()
takes an array and creates a new one with the same
contents in reverse order.For example,there are a number of ways to create an array
containing a countdown from 10 to 1.
Using
range()
usually creates an ascending sequence,which you could place in
descending order using
array
_
reverse()
or
rsort()
.Alternatively,you could create the
array one element at a time by writing a
for
loop:
$numbers = array();
for($i=10; $i>0; $i--)
array_push( $numbers, $i );
A
for
loop can go in descending order like this:You set the starting value high and at
the end of each loop use the
--
operator to decrease the counter by one.
Here, you create an empty array and then use
array_push()
for each element to add
one new element to the end of an array.As a side note,the opposite of
array_push()
is
array_pop()
.This function removes and returns one element from the end of an array.
Alternatively,you can use the
array_reverse()
function to reverse the array created
by
range()
:
$numbers = range(1,10);
$numbers = array_reverse($numbers);
Note that
array_reverse()
returns a modified copy of the array. If you do not
want the original array,as in this example,you can simply store the new copy over the
original.
If your data is just a range of integers, you can create it in reverse order by passing –1
as the optional step parameter to
range()
:
$numbers = range(10, 1, -1);
Loading Arrays from Files
In Chapter 2,“Storing and Retrieving Data,”you learned how to store customer orders
in a file.Each line in the file looked something like this:
15:42, 20th April 4 tires 1 oil 6 spark plugs $434.00 22 Short St, Smalltown
To process or fulfill this order, you could load it back into an array.Listing 3.2 displays
the current order file.
Listing 3.2 vieworders.php— Using PHP to Display Orders for Bob
<?php
//create short variable name
$DOCUMENT_ROOT = $_SERVER[‘DOCUMENT_ROOT’];
Documents you may be interested
Documents you may be interested