Slice and sort arrays with PHP
Today I would like to show you an easy way to return a portion of any array based on its start and end index. This kind of method is very useful if you want to only show part of the returned records from the database for say - pagination purposes.
Before we start slicing, I will also show you how to sort our array by its index or value.
First let's create an array. I will use a random list of a few countries in Europe. The first array we will use will not have indexes defined manually - meaning, we will only provide the values and index will be generated automatically starting from 0 up:
$countries = array( 'Luxembourg', 'Germany', 'France', 'Spain', 'Malta', 'Portugal', 'Italy', 'Switzerland', 'Netherlands', 'Belgium', 'Norway', 'Sweden', 'Finland', 'Poland', 'Lithuania', 'United Kingdom', 'Ireland', 'Iceland', 'Hungary', 'Greece', 'Georgia' );
Now, let's sort our array in the ascending order by the country name using the PHP's sort() function and return the array using the pring_r() function enclosed within the set of pre tags for better output formatting:
sort($countries); echo '<pre>'; print_r($countries); echo '</pre>';
The result of the above will be:
Array
(
[0] => Belgium
[1] => Finland
[2] => France
[3] => Georgia
[4] => Germany
[5] => Greece
[6] => Hungary
[7] => Iceland
[8] => Ireland
[9] => Italy
[10] => Lithuania
[11] => Luxembourg
[12] => Malta
[13] => Netherlands
[14] => Norway
[15] => Poland
[16] => Portugal
[17] => Spain
[18] => Sweden
[19] => Switzerland
[20] => United Kingdom
)
As you can see our array is now displaying records in the ascending order based on its values. Because we haven't manually associated array keys with the values, the array simply displays numerical index (keys) starting from 0 up.
Now let's try and sort our array in the descending (reversed) order using rsort() function:
rsort($countries); echo '<pre>'; print_r($countries); echo '</pre>';
The result now displays:
Array
(
[0] => United Kingdom
[1] => Switzerland
[2] => Sweden
[3] => Spain
[4] => Portugal
[5] => Poland
[6] => Norway
[7] => Netherlands
[8] => Malta
[9] => Luxembourg
[10] => Lithuania
[11] => Italy
[12] => Ireland
[13] => Iceland
[14] => Hungary
[15] => Greece
[16] => Germany
[17] => Georgia
[18] => France
[19] => Finland
[20] => Belgium
)
By using rsort() function we have sorted the values of our array in the ascending / reversed order, however, as you can see the index values stay unchanged - this is because (as I've mentioned before) we haven't manually specified the index for each array value.
It's all fun, but there's still more to come. Now let's create the associative array, where we manually specify the index either by using numerical or string value.
First let's create an array with numerical indexes - rather than starting from 0 - our first key / index will be 1:
$countries = array( 1 => 'Luxembourg', 2 => 'Germany', 3 => 'France', 4 => 'Spain', 5 => 'Malta', 6 => 'Portugal', 7 => 'Italy', 8 => 'Switzerland', 9 => 'Netherlands', 10 => 'Belgium', 11 => 'Norway', 12 => 'Sweden', 13 => 'Finland', 14 => 'Poland', 15 => 'Lithuania', 16 => 'United Kingdom', 17 => 'Ireland', 18 => 'Iceland', 19 => 'Hungary', 20 => 'Greece', 21 => 'Georgia' );
If we use any of the two functions discussed above we will get the exactly same result as they are used to sort the array by its values where the index is the key and the value is simply the value:
key => value
To sort array by its key / index, we need to use either ksort() function, which will sort the array by its key in the ascending order or krsort() function, which sorts the array by its key in the descending / reversed order.
Let's first try to use the ksort() function and see what the result is using our new associative array:
ksort($countries); echo '<pre>'; print_r($countries); echo '</pre>';
The result will be:
Array
(
[1] => Luxembourg
[2] => Germany
[3] => France
[4] => Spain
[5] => Malta
[6] => Portugal
[7] => Italy
[8] => Switzerland
[9] => Netherlands
[10] => Belgium
[11] => Norway
[12] => Sweden
[13] => Finland
[14] => Poland
[15] => Lithuania
[16] => United Kingdom
[17] => Ireland
[18] => Iceland
[19] => Hungary
[20] => Greece
[21] => Georgia
)
As you can see our array didn't change much, this is because we had it already sorted in the ascending order by its index / key. When using ksort() or krsort() function, values of the array are completely ignored.
Now let's try to sort our array in the ascending order using krsort() function:
krsort($countries); echo '<pre>'; print_r($countries); echo '</pre>';
The result will display:
Array
(
[21] => Georgia
[20] => Greece
[19] => Hungary
[18] => Iceland
[17] => Ireland
[16] => United Kingdom
[15] => Lithuania
[14] => Poland
[13] => Finland
[12] => Sweden
[11] => Norway
[10] => Belgium
[9] => Netherlands
[8] => Switzerland
[7] => Italy
[6] => Portugal
[5] => Malta
[4] => Spain
[3] => France
[2] => Germany
[1] => Luxembourg
)
Because we have used an associative array, where the keys / indexes are manually defined, the index is now showed in the reversed order together with its associated values.
These functions work not only on the numerical but also on the string type index. Let's amend our array slightly by replacing the numerical indexes with the alphabetical ones:
$countries = array( 'a' => 'Luxembourg', 'b' => 'Germany', 'c' => 'France', 'd' => 'Spain', 'e' => 'Malta', 'f' => 'Portugal', 'g' => 'Italy', 'h' => 'Switzerland', 'i' => 'Netherlands', 'j' => 'Belgium', 'k' => 'Norway', 'l' => 'Sweden', 'm' => 'Finland', 'n' => 'Poland', 'o' => 'Lithuania', 'p' => 'United Kingdom', 'r' => 'Ireland', 's' => 'Iceland', 't' => 'Hungary', 'u' => 'Greece', 'w' => 'Georgia' );
Now, because we have it already sorted in the alphabetical order by its keys, let's sort it in the descending / reversed order to see how it works:
krsort($countries); echo '<pre>'; print_r($countries); echo '</pre>';
The output of the above will be:
Array
(
[w] => Georgia
[u] => Greece
[t] => Hungary
[s] => Iceland
[r] => Ireland
[p] => United Kingdom
[o] => Lithuania
[n] => Poland
[m] => Finland
[l] => Sweden
[k] => Norway
[j] => Belgium
[i] => Netherlands
[h] => Switzerland
[g] => Italy
[f] => Portugal
[e] => Malta
[d] => Spain
[c] => France
[b] => Germany
[a] => Luxembourg
)
As expected, our array is now sorted in the reversed order if its indexes with their associated values.
All four of the functions mentioned above can also take another (optional) flag parameter, which modifies the sorting behaviour. If you would like to find out more about it - please visit : http://www.php.net/manual/en/function.sort.php.
Now let's have a look at how we can actually return only a portion of the array based on the specified index (position) of the item in the array.
To return only certain range of the records from the array, we will use the PHP's array_slice() function.
The array_slice() function takes the maximum of 4 and minimum of 2 parameters - these are:
1. array : the array to be processed
2. offset : the starting point of the slice (if negative the slice will start at the defined index from the end of the array)
3. length (optional) : the number of the records from the offset point. If the array is shorter than the length, then only available records will be returned
4. preserve_keys (optional - false by default) : unless used with the non-numerical associative array, the function will reorder and reset the array indexes. Set to true to preserve the associated keys / indexes
Taking our previous array with the alphabetical keys, let's now try to return the records starting from the index 6 right to the end of the array:
$result = array_slice($countries, 6); echo '<pre>'; print_r($result); echo '</pre>';
The result of the above will be:
Array
(
[g] => Italy
[h] => Switzerland
[i] => Netherlands
[j] => Belgium
[k] => Norway
[l] => Sweden
[m] => Finland
[n] => Poland
[o] => Lithuania
[p] => United Kingdom
[r] => Ireland
[s] => Iceland
[t] => Hungary
[u] => Greece
[w] => Georgia
)
As you can see from the above example the keys associated with the values have been preserved - this is because they are alphabetical. You can also see that we have only returned results starting from the 6th position / index, which in our case was letter g.
Let's now try to do the same with the new array and mixed numerical indexes like so:
$countries = array( 10 => 'Luxembourg', 25 => 'Germany', 36 => 'France', 42 => 'Spain', 55 => 'Malta', 68 => 'Portugal', 76 => 'Italy', 89 => 'Switzerland', 95 => 'Netherlands', 100 => 'Belgium', 112 => 'Norway', 125 => 'Sweden', 130 => 'Finland', 14 => 'Poland', 15 => 'Lithuania', 16 => 'United Kingdom', 17 => 'Ireland', 18 => 'Iceland', 19 => 'Hungary', 20 => 'Greece', 21 => 'Georgia' );
If we now run the same function on this array the output will be as follow:
Array
(
[0] => Italy
[1] => Switzerland
[2] => Netherlands
[3] => Belgium
[4] => Norway
[5] => Sweden
[6] => Finland
[7] => Poland
[8] => Lithuania
[9] => United Kingdom
[10] => Ireland
[11] => Iceland
[12] => Hungary
[13] => Greece
[14] => Georgia
)
Because our indexes were numerical and we did not strictly define the 4th parameter as true, the associated keys have been reset, the values however are still correct.
Now let's try to run our array_slice() function with the 4th parameter set to true, leaving the third one set to null to indicate that we wish to return all records starting from the offset parameter like so:
$result = array_slice($countries, 6, null, true); echo '<pre>'; print_r($result); echo '</pre>';
Now, because we have strictly stated that we wish to preserve the index values the result is as follow:
Array
(
[76] => Italy
[89] => Switzerland
[95] => Netherlands
[100] => Belgium
[112] => Norway
[125] => Sweden
[130] => Finland
[14] => Poland
[15] => Lithuania
[16] => United Kingdom
[17] => Ireland
[18] => Iceland
[19] => Hungary
[20] => Greece
[21] => Georgia
)
Next exercise is to provide the length parameter to only return a certain number of the records starting from the offset position. Let's use alphabetical array and call the function in the following way to only return 5 records from the 6th position:
$result = array_slice($countries, 6, 5); echo '<pre>'; print_r($result); echo '</pre>';
The result of the above will be:
Array
(
[g] => Italy
[h] => Switzerland
[i] => Netherlands
[j] => Belgium
[k] => Norway
)
It is worth to mention that unfortunately you cannot use the alphabetical / string values as the offset parameter. Only numerical index can be used to indicate what record you wish to start your slice from. The first record is always at the 0 offset, so if you wish to return a slice of the array starting from the first record use 0 for the offset.
One example we are still missing is the negative offset and length parameter.
Let's say you want to return only last 4 records from the array. To do this you would use the following:
$result = array_slice($countries, -4); echo '<pre>'; print_r($result); echo '</pre>';
which would return:
Array
(
[s] => Iceland
[t] => Hungary
[u] => Greece
[w] => Georgia
)
If you want to return say 5 records starting from the 8th record from the end of array, you would call our function in the following manner:
$result = array_slice($countries, -8, 5); echo '<pre>'; print_r($result); echo '</pre>';
This would return:
Array
(
[n] => Poland
[o] => Lithuania
[p] => United Kingdom
[r] => Ireland
[s] => Iceland
)
Lastly, to return all of the records from the array starting at the 8th position from the end of array and ending at the 2nd position, also from the end of array, you'd use the following:
$result = array_slice($countries, -8, -2); echo '<pre>'; print_r($result); echo '</pre>';
And the result would be:
Array
(
[n] => Poland
[o] => Lithuania
[p] => United Kingdom
[r] => Ireland
[s] => Iceland
[t] => Hungary
)
I hope this tutorial gives you a good overview of the things you can do with an array using the above functions.



