|
|
 |
sort (PHP 3, PHP 4, PHP 5) sort -- Sort an array Descriptionbool sort ( array &array [, int sort_flags] )
This function sorts an array. Elements will be arranged from
lowest to highest when this function has completed.
Note:
This function assigns new keys for the elements in
array. It will remove any existing
keys you may have assigned, rather than just reordering the keys.
Returns TRUE on success or FALSE on failure.
Example 1. sort() example |
<?php
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
reset($fruits);
while (list($key, $val) = each($fruits)) {
echo "fruits[" . $key . "] = " . $val . "\n";
}
?>
|
The above example will output: fruits[0] = apple
fruits[1] = banana
fruits[2] = lemon
fruits[3] = orange |
|
The fruits have been sorted in alphabetical order.
The optional second parameter sort_flags
may be used to modify the sorting behavior using these values:
Sorting type flags:
SORT_REGULAR - compare items normally
(don't change types) SORT_NUMERIC - compare items numerically SORT_STRING - compare items as strings SORT_LOCALE_STRING - compare items as
strings, based on the current locale. Added in PHP 4.3.12 and 5.0.2.
Note:
The second parameter was added in PHP 4.
| Warning |
Be careful when sorting arrays with mixed types values because
sort() can produce unpredictable results.
|
See also arsort(),
asort(), ksort(),
natsort(), natcasesort(),
rsort(), usort(),
array_multisort(), and
uksort().
User Contributed Notes
sort
hanje at hanje dot com
28-Mar-2005 04:51
During the developping of a new website, I needed a way to sort array's using a value somewhere inside a multidomensional array, while preserving the rest of the array as provided.
This is what i came up with. Comments and ideas are more then welcome as this is my first contribution to the php website. Hope it's usefull to anybody out there, could spare you some time.
The comment inside the code should explain enough. You can call the function with $order being "asc" or "desc".
The function:
<?php
function multiSortAssocR($input = array(),$priority = array(), $order = 'asc'){
$priorityKeys = array();
$ouput = array();
foreach ($input as $key => $val)
if(!($priorityKeys[$key] = priorityFind(array($val),$priority))) return false;
if ($order == 'desc') arsort($priorityKeys);
else asort($priorityKeys);
foreach ($priorityKeys as $key => $val)
$output[$key] = $input[$key];
return $output;
}
function priorityFind($input = array(),$priority = array()){
$priorityKey = key($priority);
if (!is_array($priority[$priorityKey])) $priorityKey = $priority[$priorityKey];
if (array_key_exists($priorityKey,$input)) $inputKey = $priorityKey;
else $inputKey = key($input);
if (is_array($priority[$priorityKey]))
return priorityFind($input[$inputKey],$priority[$priorityKey]);
else
return $input[$inputKey];
}
?>
a usage example:
<?php
$input = array( "foo" => array(
"abc" => array('123'),
"pri" => array('456'),
"4"
),
"bar" => array(
array('123'),
"pri" => array('1'),
"abc"
)
);
$prior = array(''=>array('pri'=>array('')));
$blaat = multiSortAssocR($input,$prior);
echo print_r($blaat);
?>
and it's output:
Array
(
[bar] => Array
(
[0] => Array
(
[0] => 123
)
[pri] => Array
(
[0] => 1
)
[1] => abc
)
[foo] => Array
(
[abc] => Array
(
[0] => 123
)
[pri] => Array
(
[0] => 456
)
[0] => 4
)
)
As you can see, it only sorts the first dimension of the array, using the key specified in $prior as sorting index.
The rest of the array remains untouched.
dwatson at planandgrow dot com
18-Mar-2005 07:55
Here is a recursive use of sort for multi-dim arrays:
<?php
function mulsort(&$a)
{
sort($a);
$c = count($a);
for($i = 0; $i < $c; $i++)
if (is_array($a[$i]))
mulsort($a[$i]);
}
$array_demo = array ( array ( array (333,1,9,8,7,6,5), array (array(1, 'x', 22), 99, 88 ), -10 ),
array ( array (11, 12, 'a', 'b', 'c'), array (8, 1, 2,-5) ) );
echo "Array before sorting:<br /><pre>";
var_dump($array_demo);
echo "</pre></ br></ br>";
mulsort($array_demo);
echo "Array after sorting:<br /><pre>";
var_dump($array_demo);
echo "</pre>";
?>
sam at jigro dot com
14-Mar-2005 06:18
Sort an array by string length...
<?php
function sort_strlen($array)
{
foreach($array as $a)
{
$new[] = strlen($a) . '|||' . $a;
}
sort($new);
foreach ($new as $n)
{
$split = explode('|||',$n);
$retval[] = $split[1];
}
return $retval;
}
?>
-toCra
Direc
27-Feb-2005 06:12
<?php
$list[] = "me";
$list[] = "you";
$list[] = "he";
$list[] = "she";
$list = usort($list, strcasecmp);
?>
timc at hlyw dot com
17-Feb-2005 06:04
I dig the multi_sort function(s) from above. But, they don't work for hash arrays. I added a keys variable to keep track of the key value as the array gets sorted. Feed back welcome.
<?php
function array_qsort (&$array, $column=0, $order=SORT_ASC, $first=0, $last= -2)
{
$keys = array_keys($array);
if($last == -2) $last = count($array) - 1;
if($last > $first) {
$alpha = $first;
$omega = $last;
$key_alpha = $keys[$alpha];
$key_omega = $keys[$omega];
$guess = $array[$key_alpha][$column];
while($omega >= $alpha) {
if($order == SORT_ASC) {
while($array[$key_alpha][$column] < $guess) {$alpha++; $key_alpha = $keys[$alpha]; }
while($array[$key_omega][$column] > $guess) {$omega--; $key_omega = $keys[$omega]; }
} else {
while($array[$key_alpha][$column] > $guess) {$alpha++; $key_alpha = $keys[$alpha]; }
while($array[$key_omega][$column] < $guess) {$omega--; $key_omega = $keys[$omega]; }
}
if($alpha > $omega) break;
$temporary = $array[$key_alpha];
$array[$key_alpha] = $array[$key_omega]; $alpha++;
$key_alpha = $keys[$alpha];
$array[$key_omega] = $temporary; $omega--;
$key_omega = $keys[$omega];
}
array_qsort ($array, $column, $order, $first, $omega);
array_qsort ($array, $column, $order, $alpha, $last);
}
}
?>
eyhk
08-Feb-2005 02:27
Great thanks to "info AT cpgnuke DOT com" for your last year's post on sorting case-insensitive strings!
fred at ocn dot com dot br
13-Nov-2004 05:11
---[ Editor's Note ]---
You can use array_values() from PHP, which is a lot faster and easier.
---[ End Note ]---
To sort and re-index the array you could use function below:
Ex:
<?
function array_reindex($array)
{
$quant=count($array);
$j=0;
$i=0;
while ($j < $quant)
{
if ($array[$i]<>"")
{
$array_reindex[$j]=$array[$i];
$j++;
}
$i++;
}
return($array_reindex);
}
print_r($users);
Return: Array ( [1] => Fred [2] => Erika )
$users=sort($users)
Return: Array ( [1] => Erika [2] => Fred )
$users=array_reindex($users);
Return: Array ( [0] => Erika [1] => Fred )
?>
anthony at ectrolinux dot com
08-Sep-2004 06:39
In a brief addition to the previous poster's message, the ascending sorting order used by PHP directly corresponds to ISO-8859-1 (ASCII). Therefore the character \48 (numeral 0) would be placed before the character \82 (R), which would be placed before the character \110 (n), and so forth.
teunkloosterman at hotmail dot com
30-Aug-2004 03:14
Just to show how it sorts:
<?php
$array = Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", " ", "!", "@", "#", "\\\$", "%", "^", "&", "*", "(", ")", "_", "-", "=", "+", "\\\\", "|", ",", "<", ".", ">", "?", "'", "\\\"", "`", "~");
sort($array);
echo implode("", $array);
?>
returns:
!"#$%&'()*+,-.0123456789<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ
\^_`abcdefghijklmnopqrstuvwxyz|~
note: the result begins with a space
Gerhard Conradi
10-Mar-2004 02:49
Hi @all,
to my previous author: thanks, thanks, thanks! Works great and saved me lot of time. I added an extension for ascending/descending order. Here are the changes:
// first i defined two constants for asc and desc
// you can skip that, but then you have to change the switch command at the end of the function
define("ORDER_ASC", "asc");
define("ORDER_DESC", "desc");
function mu_sort($array, $key_sort, $asc_desc) { // start function
// check input parameters
if (func_num_args()<2 || func_num_args()>3) die("Wrong number of parameters for the call of mu_sort()");
$array = func_get_arg(0);
$key_sort = func_get_arg(1);
if (func_num_args()==3)
$asc_desc = func_get_arg(2);
else
$asc_desc = ORDER_ASC;
$key_sorta = explode(",", $key_sort);
.... // from here it's exactly the same
... // until here
} // end loop #2
} // end loop #1
// sort
// if you don't want to use the constants defined at the top, change here to whatever you're using
switch($asc_desc) {
case ORDER_DESC:
rsort($output); break;
default:
sort($output);
}
// return sorted array
return $output;
} // end function
Now you can call the function like this:
mu_sort($array, $key_sort, ORDER_DESC);
or even:
mu_sort($array, $key_sort); // This will sort the array by default ascending
Have fun...
admin at lavacube dot net
13-Feb-2004 10:34
Please discard my previous post[perhaps an admin can deleted it for me? :-)]. It turns out the original script I implemented it in didn't seem to work properly. After more development, I did find a method that works as theorized in my previous post. I also added in a new function. What it does is allows you to add in multiple key names, it will then sort them in that order, the purpose is, is that if the first one is the same throughout, it will jump to the next key.
Here's the script:
<?php
$array[0][username] = "user_name";
$array[0][password] = "pass_word";
$array[0][account_type] = "admin";
$array[1][username] = "eman_resu";
$array[1][password] = "drow_ssap";
$array[1][account_type] = "user";
$array[2][username] = "php_roxs";
$array[2][password] = "yesitdoes";
$array[2][account_type] = "admin";
$sorted = mu_sort($array, "password,account_type");
print_r($sorted);
function mu_sort ($array, $key_sort) { $key_sorta = explode(",", $key_sort);
$keys = array_keys($array[0]);
for($m=0; $m < count($key_sorta); $m++){ $nkeys[$m] = trim($key_sorta[$m]); }
$n += count($key_sorta); for($i=0; $i < count($keys); $i++){ if(!in_array($keys[$i], $key_sorta)){
$nkeys[$n] = $keys[$i];
$n += "1";
} } for($u=0;$u<count($array); $u++){ $arr = $array[$u];
for($s=0; $s<count($nkeys); $s++){
$k = $nkeys[$s];
$output[$u][$k] = $array[$u][$k];
} } sort($output);
return $output;
} ?>
// +------------------------------------------------------
// And here are the results from the print_r function
// +------------------------------------------------------
Array
(
[0] => Array
(
[password] => drow_ssap
[account_type] => user
[username] => eman_resu
)
[1] => Array
(
[password] => pass_word
[account_type] => admin
[username] => user_name
)
[2] => Array
(
[password] => yesitdoes
[account_type] => admin
[username] => php_roxs
)
)
P.S. - Sorry for the lengthly un-neat function. But it does work. You are welcome to modify it as you wish. If someone could clean it up and use not so many loops, that would be great.
info AT cpgnuke DOT com
21-Jan-2004 11:26
i think this is an easier and pratical way for sorting case insenisitve
function cmp($a, $b) {
return strcmp(strtolower($a), strtolower($b));
}
$fruits[] = "lemons";
$fruits[] = "apples";
$fruits[] = "grapes";
usort($fruits, "cmp");
metalwyrm at fastmail dot fm
20-Jan-2004 11:09
because sort() is case sensitive, I made a function using
sort() that is case insensitive
function iSort($sortarr) {
$bakarr = $sortarr;
for($arrnum = 0; $arrnum < Count($sortarr); $arrnum++) {
$sortarr[$arrnum] = strtolower($sortarr[$arrnum])."|".$arrnum;
}
sort($sortarr);
reset($sortarr);
for($arrnum = 0; $arrnum < Count($sortarr); $arrnum++) {
$temp = explode("|", $sortarr[$arrnum]);
$newarr[] = $bakarr[$temp[Count($temp)-1]];
}
return $newarr;
}
jordijolink at hotmail dot com
16-Dec-2003 10:34
This is a sorting function that will NOT look at case sensitivity:
function DoSort($List1) {
$List2 = $List1;
for ($Loop = 0; $Loop < sizeof($List1); $Loop++) {
$List1[$Loop] = $List1[$Loop] . "|" . $Loop;
$List2[$Loop] = strtolower($List2[$Loop]) . "|" . $Loop;
}
sort($List2);
reset($List2);
$TempVar = explode("|", $List2[0]);
$TempInt = $TempVar[1];
$NewListNE = "\n" . $List1[$TempInt];
for ($Loop = 1; $Loop < sizeof($List1); $Loop++) {
$TempVar = explode("|", $List2[$Loop]);
$TempInt = $TempVar[1];
$NewListNE .= "\n" . $List1[$TempInt];
}
$NewList = explode("\n", $NewListNE);
for ($Loop = 0; $Loop < sizeof($NewList); $Loop++) {
$TempVar = explode("|", $NewList[$Loop]);
$NewList[$Loop] = $TempVar[0];
}
return $NewList;
}
edu_chaos at yahoo dot com dot br
13-Oct-2003 11:09
A simple sort 2 array 1D (bublesort)
<?php
$tam = sizeof($arr ) ;
$i=0;
$aux=0;
$change = true;
while( $i<$tam && $change ):
$j=0;
$troca = false;
while( $j < $tam-$i-1 ):
if( $arr[$j] > $arr[$j+1] ):
$aux = $arr[$j];
$arr[$j] = $arr[$j+1];
$arr[$j+1] = $aux;
$troca = true;
endif;
$j++;
endwhile;
$i++;
endwhile;
?>
05-Apr-2003 09:24
Written by George Andre P.
Here is Insertion Sort, that preserves the keys of the array while it sorts the values. Works for 1D array whose keys are positive integers I think :)
function insertionSort($str_) {
foreach ($str_ as $key => $val) {
$val_[] = $val;
$key_[] = $key;
}
for ($i = 1; $i < count ($val_); $i++) {
$index = $val_[$i];
$kindex = $key_[$i];
$j = $i;
while (($j > 0) && ($val_[$j - 1] > $index)) {
$val_[$j] = $val_[$j - 1];
$key_[$j] = $key_[$j - 1];
$j = $j - 1;
}
$val_[$j] = $index;
$key_[$j] = $kindex;
}
foreach ($val_ as $key => $val) {
$new_[$key_[$key]] = $val;
}
return $new_;
}
Here is test to prove the functionality of the sort:
// Test insertionSort.
if (isSet ($sorted_)) {
foreach ($sorted_ as $key => $val) {
echo $key . ' => ' . $val . '<br>';
}
}
Enjoy. Hope that helps some one.
Remember: Knowledge Bellongs To The Universe. Share it!
I know I probably have said this a million times, but PHP Developers thanks for PHP again!
Rich Christiansen
27-Mar-2003 12:28
Trying to sort an array without regard to case (case insensitive?) Try usort(). I needed to sort an associated array without regard to case and this is what I came up with, from modifying the example from the documentation for usort().
function cmp ($a, $b)
{
return strcasecmp($a["field_name"], $b["field_name"]);
}
uasort($array, "cmp");
-RIch
matias at arenasoftware dot com
23-Mar-2003 07:36
Lets say you have the following array:
$array1 = Array(third => "Some text 3", second => "Some text 2", first => "Some text 1", fourth => "Some text 4" );
and you want to sort it by first,second,third, fourth.
Very easy! Just create a second array:
$array2 = Array(first => "", second => "", third => "", fourth => "");
and do:
$result = array_merge($array2,$array1);
now $result = Array(first => "Some text 1",second => "Some text 2",third => "Some text 3",fourth => "Some text 4");
This is very usefull when you want to print data out of a database table for example, but you would like to give it a custom order.
arjan321 at hotmail dot com
31-Jan-2003 02:23
Ik you want to sort case insensitive, use the natcasesort()
bpiere21 at hotmail dot com
23-Dec-2002 09:42
Use the function "ksort" to maintain correlations.
mbevan at marginsoftware dot com
03-Dec-2002 03:21
I've noticed that if you try to sort an assoc. array, it strips the names of the elements, as can be seen by the following code and it's output:
<?php
$fruitcolors = array ("lemon"=>"yellow",
"orange"=>"orange",
"banana"=>"yellow",
"apple"=>"red");
sort ($fruitcolors);
reset ($fruitcolors);
print_r($fruitcolors);
}
?>
Output:
Array
(
[0] => orange
[1] => red
[2] => yellow
[3] => yellow
)
Which is useless if the name of each element is important (as it is in the above example). How to sort the above array without loosing the keys? There has to be a simple way of doing this that is elusive to me.
shailu_agrawal at yahoo dot no_spam dot com
13-Nov-2002 08:05
if 2nd parameter is "SORT_REGULAR" it will compare characters by ASCII values.
For ex: if unsorted values are: B , a , A
with SORT_REGULAR sorted result will be: A , B , a
and with SORT_STRING sorted result will be: a , A , B
whit at transpect dot com
25-Oct-2002 06:54
As I was prettying up the output I realized that removing that "-1" from the function creates an extra blank line in the array - but still is the only way I've found to get the final real line sorted. Here is the kludged version of my tabbed-ASCII table displayer that uses the function, which won't show the extra line if the value in the first column is empty. It also has an extra variable to set up top, $title. Other than that, it's to be pasted in place of the last half of the code in my post here just prior:
$mem=file("$infile");
$line=explode("\t","$mem[0]");
$cnt=count($line);
echo "<html><head><title>$title</title></head><body link=\"#ffff00\" alink=\#ff0000\" vlink=\"#00ffff\">";
echo "<table border=\"1\">";
echo "<tr><td colspan=\"$cnt\" bgcolor=\"#cc0000\"><font size=\"5\" color=\"#ffffff\">$title</font></td></tr><tr>";
for ($i=$firstcol;$i<$cnt;$i++) {
echo "<td bgcolor=\"#000000\"><a href=\"$PHP_SELF?col=$i\">$line[$i]</a></td>";
}
echo "</tr>";
$cnt=count($mem);
for ($i=$firstcol;$i<$cnt;$i++) {
$line=explode("\t","$mem[$i]");
$cnt2=count($line);
for ($j=$firstcol;$j<$cnt2;$j++) {
$mem2[$i][$j]=$line[$j];
}
}
if(!isset($col)) $col=$firstcol;
$mem2=qsort_multiarray($mem2,$col);
$x=1;
for ($i=0;$i<$cnt;$i++) {
for ($j=$firstcol;$j<$cnt2;$j++) {
if ($mem2[$i][$firstcol]!="") {
if ($j==$firstcol) {
if ($x=="1") {
echo "<tr>";
$x=0;
} else {
echo "<tr bgcolor=\"#dddddd\">";
$x=1;
}
}
$show=$mem2[$i][$j];
if ($show=="") $show=" ";
echo "<td>$show</td>";
if ($j==($cnt2-1)) echo "</tr>";
}
}
}
echo "</table></body></html>";
whit at transpect dot com
25-Oct-2002 04:06
fmmarzoa's qsort_multiarray gets the last record with the removal of a "-1" from the 3rd line of the function definition. Here's a routine using it that takes a tab-delimited table with the column names in the first row, and displays it from an arbitrary column on the left to the last on the right with option to sort by any one column:
<?php
$infile="members.txt";
$firstcol="1";
function qsort_multiarray($array, $num = 0, $order = "ASC", $left = 0, $right = -1) {
if($right == -1) {
$right = count($array);
}
$links = $left;
$rechts = $right;
$mitte = $array[($left + $right) / 2][$num];
if($rechts > $links) {
do {
if($order == "ASC") {
while($array[$links][$num]<$mitte) $links++;
while($array[$rechts][$num]>$mitte) $rechts--;
} else {
while($array[$links][$num]>$mitte) $links++;
while($array[$rechts][$num]<$mitte) $rechts--;
}
if($links <= $rechts) {
$tmp = $array[$links];
$array[$links++] = $array[$rechts];
$array[$rechts--] = $tmp;
}
} while($links <= $rechts);
if ($left < $rechts) $array = qsort_multiarray($array,$num,$order,$left, $rechts);
if ($links < $right) $array = qsort_multiarray($array,$num,$order,$links,$right);
}
return $array;
}
$mem=file("$infile");
$line=explode("\t","$mem[0]");
$cnt=count($line);
echo "<html><head><title>$infile</title></head><body>";
echo "<table border=\"1\"><tr>";
for ($i=$firstcol;$i<$cnt;$i++) {
echo "<td><a href=\"$PHP_SELF?col=$i\">$line[$i]</a></td>";
}
echo "</tr>";
$cnt=count($mem);
for ($i=$firstcol;$i<$cnt;$i++) {
$line=explode("\t","$mem[$i]");
$cnt2=count($line);
for ($j=$firstcol;$j<$cnt2;$j++) {
$mem2[$i][$j]=$line[$j];
}
}
if(!isset($col)) $col=$firstcol;
$mem2=qsort_multiarray($mem2,$col);
for ($i=0;$i<$cnt;$i++) {
echo "<tr>";
for ($j=$firstcol;$j<$cnt2;$j++) {
$show=$mem2[$i][$j];
echo "<td>$show</td>";
}
echo "</tr>";
}
echo "</table></body></html>";
?>
whit at transpect dot com
25-Oct-2002 03:09
<p>fmmarzoa's qsort_multiarray above works <i>except</i>:
<br>It's case-sensitive
<br>It doesn't sort the last record - which ends up just sitting at the end of the array, whether or not it belongs there in the sort
fmmarzoa at gmx dot net
16-Oct-2002 05:18
As someguys has note, there's a bug in the qsort_multiarray function. They've offered some workarounds, but I think that the trouble its just that the algoritm is bad implemented, so here's my solution:
function qsort_multiarray($array, $num = 0, $order = "ASC", $left = 0, $right = -1) {
if($right == -1) {
$right = count($array) - 1;
}
$links = $left;
$rechts = $right;
$mitte = $array[($left + $right) / 2][$num];
if($rechts > $links) {
do {
if($order == "ASC") {
while($array[$links][$num]<$mitte) $links++;
while($array[$rechts][$num]>$mitte) $rechts--;
} else {
while($array[$links][$num]>$mitte) $links++;
while($array[$rechts][$num]<$mitte) $rechts--;
}
if($links <= $rechts) {
$tmp = $array[$links];
$array[$links++] = $array[$rechts];
$array[$rechts--] = $tmp;
}
} while($links <= $rechts);
if ($left < $rechts) $array = qsort_multiarray($array,$num,$order,$left, $rechts);
if ($links < $right) $array = qsort_multiarray($array,$num,$order,$links,$right);
}
return $array;
}
Note the two "ifs" after the do {} while stub.
06-Jun-2002 05:59
Regarding sort not touching single element arrays, use the following code to cope:
if( count($ids) == 1 )
{
$ids = array( array_pop($ids) );
}
matthew at sagacity dot com dot au
02-Jun-2002 02:31
I needed to sort a multi-dimensional football results array by two columns; first by competition points then by for/against. As they were both numerical values I was able to simply add the competition points to the for/against divided by 100.
e.g.
Points Goals
Team 1: 0 -1 Team 3: +3.02
Team 2: 3 +1 became Team 2: +3.01
Team 3: 3 +2 (once sorted) Team 1: -0.01
Team 4: 0 -2 Team 4: -0.02
If your second column is likely to contain larger numbers, divide by a higher power of 10.
Otherwise a team with 10 competion points and 51 goals against [10 + (-51 / 100) = 9.49] would sort below a team with 9 competition points and 51 goals for [9 + (51 / 100) = 9.51]).
Dividing by 1000 in this case would give you 9.949 and 9.051 (which would sort correctly).
Hope I made that clear!
rob at pulpchat dot com
30-May-2002 02:44
Here is a simple, CASE-INSENSITIVE sort function
that allows you to specify the starting point and/or
ending point in an array. This can be quite useful
if you want to leave the first n elements alone, etc.
function QSortLCase(&$xArray,$lower=0,$upper=0) {
//v06.15.01, PHP version 05.29.02
//xArray is passed by reference
$xLow=$lower;
if ($upper==0) {$upper=count($xArray)-1;}
$xHigh=$upper;
if ($upper <= $lower) {return;}
$midPoint = floor(($lower + $upper)/2);
$strTemp = strtolower($xArray[$midPoint]);
while ($xLow<=$xHigh) {
while (strtolower($xArray[$xLow])<$strTemp) {
$xLow++;
if ($xLow==$upper) {break;}
}
while ($strTemp<strtolower($xArray[$xHigh])) {
$xHigh--;
if ($xHigh==$lower) {break;}
}
if ($xLow<=$xHigh) {
$strBuffer=$xArray[$xLow];
$xArray[$xLow]=$xArray[$xHigh];
$xArray[$xHigh]=$strBuffer;
$xLow++;
$xHigh--;
}
}
if ($lower<$xHigh) {QSortLCase($xArray,$lower,$xHigh);}
if ($xLow<$upper) {QSortLCase($xArray,$xLow,$upper);}
}
Examples of using this function:
--------------------------------
QSortLCase($myArray); //sorts all elements of the array
QSortLCase($myArray,1); //ignores element 0, sorts the rest
QSortLCase($myArray,5,25); //only sorts elements 5 through 25
QSortLCase($myArray,7,8); //only sorts elements 7 and 8
I originally wrote this function in another language
because a good quick sort function was not available.
Although there are many ways to perform sorting in PHP,
I created this PHP version because it is the simplest way
I could find to do exactly what I needed. Hopefully it
will help someone.
oatmealrox AMPERSAND hotmail PERIOD com
21-May-2002 12:49
Here's my simple solution to an array not being sorted alpahbetically when capitals are involved:
$strings[0]="blue";
$strings[1]="red";
$strings[2]="green";
#Set the key values of a new array to a lowercase version of each string value.
foreach($strings as $one_string){
$array[strtolower($one_string)] = $one_string;
}
#then sort by the keys...
ksort($array);
Now the array $array is your original array but in alphabetical order. Of course, you can only use this if the key values don't need to be preserved.
14-Mar-2002 04:09
If you want to sort an array according to your locale do the following:
(de_DE as example)
setlocale("LC_ALL","de_DE");
usort($arraytobesorted, 'strcoll');
RunMaster at gmx dot de
29-Aug-2001 12:11
Note that sort() is void, so an assignment like
$foo_array = sort( $foo_array );
wont work. In result you cannot combine sort() for use with other array-related functions just like array_unique() or array_values(). None of the following statements works:
sort( array_unique( $foo_array ) );
// returns empty string
$foo_array = array_unique( sort( $foo_array) );
// returns parameter failure
The only way to combine those functions is to apply sort() in a single line statement.
So please dont waste your time with hours of debugging like me before I found out, its void... ;-)
RunMaster at gmx dot de
27-Aug-2001 08:56
E ~ É topic
sort() sorts in ASCII where É is higher than E (even as Z) so there is no way without a workaround.
My suggestion is to try out the following:
str_replace() all the É and other special chars with an E or any similar fitting char and an identification string just like ++, which should not appear in any of the strings used in the array ("E++somethingelseinfrench").
sort() your array and str_replace() its elements again, this time replace E++ with É.
This should bring all your És just after E, before F...
This is not the best solution, but should help a bit.
erik at cobram dot com dot br
12-Jul-2001 12:21
Just to extend the topic re: sorting arrays with just one item... I have had the same problem!
I don't remember anything in the books I read about this, and haven't seen it in the manual, but here's what I did to fix the problem for me:
if ($link_keys){
if (count($link_keys) <= 1){
array_push($link_keys, "-");
echo "<br>Link_keys:<br>";
rsort($link_keys);
array_pop ($link_keys);
while (list($lvar, $lvalue) = each($link_keys)){
echo "$lvar = $lvalue<br>"; //DEBUG: Shows $post_vars_keys index and values.
}
}
else {
sort($link_keys);
echo "<br>Link_keys:<br>";
//echo "Num of Elements: " . count($link_keys) . "<br>";
while (list($lvar, $lvalue) = each($link_keys)){
echo "$lvar = $lvalue<br>"; //DEBUG: Shows $post_vars_keys index and values.
}
}
}
It basically says: if such an array exists and its size is less than or equal to 1 [element], add a "dummy" entry, reverse sort it and pop-off the last item -> which should be the dummy entry! array[1] becomes array[0]! Else sort the array just the way it is.
Ofcourse, this assumes you have consistent entries in your arrays to be sorted or at least: that you use some distinct character which YOU KNOW won't appear in the life of that array.
Hope this helps at least some people!!!
phpdotnetNO_SPAM at electronic-strategy dot com
05-Jul-2001 11:34
/*
Small function to Alphabetically sort Multidimensional arrays by index values of an n dimension array.
I have only tested this for sorting an array of up to 6 dimensions by a value within the second dimension. This code is very rough and works for my purposes, but has not been tested beyond my needs.
Although a little clunky and not a mathematical type algorithm, it get's the job done. It theoretically overcomes many of the problems I have seen with multidimensional arrays in that it is possible to specify within the function, not by reference :-(, which index you wish to sort by, no matter how many dimensions down.
call function by assigning it to a new / existing array:
$row_array = multidimsort($row_array);
*/
function multidimsort($array_in) {
$multiarray = array();
$array_out = array();
$loopvalue = 0;
/* -1 as traversal of array starts from 0, count() starts from 1 */
$multicount = count($array_in) - 1;
/* add the indexes you wish to sort array by to a new array in this case index is two levels down, but shouldn't make a difference if it goes further indexes down. (Not tested!) */
for($i = 0; $i <= $multicount; $i++) {
array_push($multiarray, $array_in[$i][2]);
//array_push($multiarray, $array_in[$i][2][4]);
//array_push($multiarray, $array_in[$i][1][3][7]);
}
/* alphabetically sort the new array (Ascending in this case) can chage sort to whatever type you like. Even apply user-defined sort. */
asort($multiarray);
/* reset internal pointer to beginning of array after above sort */
reset($multiarray);
/* traverse new array of index values and add the corresponding element of the input array to the correct position in the output array */
while (list ($key, $val) = each ($multiarray)) {
$array_out[$loopvalue] = $array_in[$key];
$loopvalue++;
}
/* return the output array which is all nicely sorted by the index you wanted! */
return $array_out;
}
Richard dot C dot Mitchell at Boeing dot com
23-Apr-2001 11:59
The usort function can be used to sort multi-dimension arrays, also.
To do a case-insensitive sort on the 7th column of a two-dimensional array:
usort($listing, create_function('$a,$b','return strcasecmp($a[7],$b[7]);'));
When using associative arrays:
usort($listing, create_function('$a,$b','return strcasecmp($a["name"],$b["name"]);'));
Case-sensitive, descending (just change '$a,$b' to '$b,$a'):
usort($listing, create_function('$b,$a','return strcmp($a["name"],$b["name"]);'));
A two-dimensional array of numbers (7th column, ascending):
usort($listing, create_function('$a,$b','return $a[7]==$b[7]?0:($a[7]<$b[7]?-1:1);'));
Richard dot C dot Mitchell at Boeing dot com
18-Apr-2001 06:26
I found an error in the qsort_multiarray() function posted above. The last argument ($right) should have a default value less than -1, because -1 can occur in a recursive call to the function. I have re-written (and renamed) the function to fix that problem and to make it more efficient. I also renamed the variables and added comments.
----------------------- cut here -----------------------
<?php function array_qsort2 (&$array, $column=0, $order=SORT_ASC, $first=0, $last= -2)
{
if($last == -2) $last = count($array) - 1;
if($last > $first) {
$alpha = $first;
$omega = $last;
$guess = $array[$alpha][$column];
while($omega >= $alpha) {
if($order == SORT_ASC) {
while($array[$alpha][$column] < $guess) $alpha++;
while($array[$omega][$column] > $guess) $omega--;
} else {
while($array[$alpha][$column] > $guess) $alpha++;
while($array[$omega][$column] < $guess) $omega--;
}
if($alpha > $omega) break;
$temporary = $array[$alpha];
$array[$alpha++] = $array[$omega];
$array[$omega--] = $temporary;
}
array_qsort2 ($array, $column, $order, $first, $omega);
array_qsort2 ($array, $column, $order, $alpha, $last);
}
}
?>
----------------------- cut here -----------------------
<?php require_once("qsort2.php");
$cat = Array(
Array( 1,3 ),
Array( 0,6 ),
Array( 5,2 ),
Array( 8,4 ),
);
print "<pre>";
print_r($cat);
array_qsort2 ($cat, 1, SORT_DESC);
print_r($cat);
print "</pre>";
?>
----------------------- cut here -----------------------
<?php require_once("qsort2.php");
$numbers = Array(
Array ( "number"=>1, "english"=>"one", "spanish"=>"uno" ),
Array ( "number"=>2, "english"=>"two", "spanish"=>"dos" ),
Array ( "number"=>3, "english"=>"three", "spanish"=>"tres" ),
Array ( "number"=>4, "english"=>"four", "spanish"=>"cuatro" ),
Array ( "number"=>5, "english"=>"five", "spanish"=>"cinco" ),
);
print "<pre>";
print_r($numbers);
array_qsort2 ($numbers, "spanish");
print_r($numbers);
print "</pre>";
?>
----------------------- cut here -----------------------
peek at mailandnews dot com
07-Apr-2001 06:06
I ran into the same problem with case insensitive sorting. Actually I think there should be a SORT_STRING_CASE flag but I tried the following:
usort($listing, 'strcasecmp');
This didn't work (why not?), but you can do a proper case insensitive sort like this:
usort($listing, create_function('$a,$b','return strcasecmp($a,$b);'));
tim at sod dot co dot uk
26-Mar-2001 08:40
I was looking for a way to sort an array alphabetically. The first post points out that 'Ab' is different to 'AB' and you can't make it case insensitive (well, I couldn't). So I did it like this:<br><br>
function cmp ($a, $b) {
$tmp[0]=strtoupper($a);
$tmp[1]=strtoupper($b);
sort($tmp);
return (strcmp(strtoupper($tmp[1]) , strtoupper($b))) ? 1 : -1;
}
$listing[0]="AB";
$listing[1]="yzZAZz";
$listing[2]="YZzazZ";
$listing[3]="LhaASD";
$listing[4]="A";
$listing[5]="aB";
usort($listing, "cmp");
echo implode(",",$listing);
<br><br>
Which produces: <br>A,AB,aB,LhaASD,yzZAZz,YZzazZ
spamt at maro dot net
22-Mar-2001 05:17
I tried the above quicksort clip and it would send my script into an endless loop every time. A little more investigation into sorting multi-dimentional arrays resulted in finding how to implement the array_multisort function properly to do this. Array_multisort lets you take a multi-dimentional array and sort by one column, keeping all your rows in line. Here's what I did:
With a two dimentional array of numbers stored in cat[X][Y], I wanted to sort by the second column of numbers (descending), but have it keep the corresponding number in the first column lined up with it's partner.
CAT: 0 1 <- X
__Y____________
: 1: 1 3
: 2: 0 6
: 3: 5 2
: 4: 8 4
To result in:
CAT: 0 1 <- X
__Y____________
: 1: 0 6
: 2: 8 4
: 3: 1 3
: 4: 5 2
array_multisort($cat[1], SORT_NUMERIC, SORT_DESC, $cat[0]);
Richard dot C dot Mitchell at Boeing dot com
22-Mar-2001 03:20
The function submitted by CK1 -- qsort_multiarray() -- will also work with associative arrays.
----------------------------------------------
$array = Array(
Array ( "dog"=>"value3", "cat"=>"4", "mouse"=>"element2" ),
Array ( "dog"=>"value4", "cat"=>"3", "mouse"=>"element1" ),
Array ( "dog"=>"value2", "cat"=>"1", "mouse"=>"element3" ),
Array ( "dog"=>"value1", "cat"=>"2", "mouse"=>"element4" )
);
$array = qsort_multiarray($array,"cat");
CK1 at wwwtech dot de
08-Feb-2001 10:00
Hi,
sorry for spamming ;)
But I forgot the ASC DESC feature. Just change the function to the following:
function qsort_multiarray($array,$num = 0,$order = "ASC",$left = 0,$right = -1)
{
if($right == -1)
{ $right = count($array) - 1; }
$links = $left;
$rechts = $right;
$mitte = $array[($left + $right) / 2][$num];
if($rechts > $links)
{
do
{
if($order == "ASC")
{
while($array[$links][$num]<$mitte) $links++;
while($array[$rechts][$num]>$mitte) $rechts--;
}
else
{
while($array[$links][$num]>$mitte) $links++;
while($array[$rechts][$num]<$mitte) $rechts--;
}
if($links <= $rechts)
{
$tmp = $array[$links];
$array[$links++] = $array[$rechts];
$array[$rechts--] = $tmp;
}
} while($links <= $rechts);
$array = qsort_multiarray($array,$num,$order,$left, $rechts);
$array = qsort_multiarray($array,$num,$order,$links,$right);
}
return $array;
}
Call the function like this:
$array = qsort_multiarray(array $array,int $n,string $order,int $left,int $right);
$array is the array which should be sorted, int $n is the index of the sort criterium, $order is "ASC" or "DESC" for ascending sorting or descending sorting, $left is the left index and $right is the right index.
The default sort is ASC. $left and $right are optional.
Greets,
CK1
http://wwwtech.de
x-itec at freenet dot de
20-Aug-2000 09:59
Maybe u have a problem that you can not sort your array if the array contains only numbers. The solution: The numbers are sorted as ASCII, you have to store values to your array in this form as an example:
$artikelarray[$x]=intval($row188[id]);
You have to use INTVAL to convert your Number to a numeric value! Now you can sort your array with sort($artikelarray) and it works finde.
Boris Köster
ultrafunkula at mad dot scientist dot com
31-Mar-2000 12:08
What you really want is asort(). The neat thing about PHP arrays is that even though they have a traditional numerical index, they are not defined by it. What I mean by this is if you define an array $data[], then $data[2] does not necessarily exist between $data[1] and $data[3].
So if you asort() by the artist name and then use each() to recover the array elements in the order they exist(rather than an incremental loop which ties you to their arbitrary numerical key), you can sort your data by any dimension of your array. Try this out:
$data[0][1]='Title 2';
$data[0][2]='Title 1';
$data[0][0]='Title 3';
$data[1][1]='Barney';
$data[1][0]='Charlie';
$data[1][2]='Al';
$data[2][2]='Sing the song of Al';
$data[2][1]='Jam with Barney';
$data[2][0]='Charlie Rocks';
while (list($key) = each($data[1])) {
print $data[0][$key].",".$data[1][$key].",".$data[2][$key]."<p>";
}
asort($data[1]);
while (list($key) = each($data[1])) {
print $data[0][$key].",".$data[1][$key].",".$data[2][$key]."<p>";
}
The interesting part is that the first, UNSORTED array doesn't come out in numerical order, because it wasn't put in that way. If you asort($data[2]) you'll sort by lyrics, and so on. Just make sure you remember to each() by the same dimension as you asort().
misillet at tin dot it
17-Mar-2000 12:58
Note that using sort() it seems to sort by ASCII code, because "AC" is before "Ab" in the result array
| |