数组 函数
在线手册:中文 英文
PHP手册

sort

(PHP 4, PHP 5)

sort对数组排序

说明

bool sort ( array &$array [, int $sort_flags ] )

本函数对数组进行排序。当本函数结束时数组单元将被从最低到最高重新安排。

Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名,而不是仅仅将键名重新排序。

成功时返回 TRUE, 或者在失败时返回 FALSE.

Example #1 sort() 例子

<?php

$fruits 
= array("lemon""orange""banana""apple");
sort($fruits);
foreach (
$fruits as $key => $val) {
    echo 
"fruits[".$key."] = " $val "\n";
}

?>

以上例程会输出:

fruits[0] = apple
fruits[1] = banana
fruits[2] = lemon
fruits[3] = orange

fruits 被按照字母顺序排序。

可选的第二个参数 sort_flags 可以用以下值改变排序的行为:

排序类型标记:

Note:

第二个参数是 PHP 4 新加的。

Warning

在对含有混合类型值的数组排序时要小心,因为 sort() 可能会产生不可预知的结果。

参见 arsort()asort()ksort()krsort()natsort()natcasesort()rsort()usort()array_multisort()uksort()

参数

array

The input array.

sort_flags

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.4.0 and 5.0.2, it uses the locale, which can be changed using setlocale().
  • SORT_NATURAL - compare items as strings using "natural ordering" like natsort(). Added in PHP 5.4.0.
  • SORT_FLAG_CASE - can be combined (bitwise OR) with SORT_STRING or SORT_NATURAL to sort strings case-insensitively. Added in PHP 5.4.0.

返回值

成功时返回 TRUE, 或者在失败时返回 FALSE.

范例

Example #2 sort() example

<?php

$fruits 
= array("lemon""orange""banana""apple");
sort($fruits);
foreach (
$fruits as $key => $val) {
    echo 
"fruits[" $key "] = " $val "\n";
}

?>

以上例程会输出:

fruits[0] = apple
fruits[1] = banana
fruits[2] = lemon
fruits[3] = orange

The fruits have been sorted in alphabetical order.

Example #3 sort() example using case-insensitive natural ordering

<?php

$fruits 
= array(
    
"Orange1""orange2""Orange3""orange20"
);
sort($fruitsSORT_NATURAL SORT_FLAG_CASE);
foreach (
$fruits as $key => $val) {
    echo 
"fruits[" $key "] = " $val "\n";
}

?>

以上例程会输出:

fruits[0] = Orange1
fruits[1] = orange2
fruits[2] = Orange3
fruits[3] = orange20

The fruits have been sorted like natcasesort().

注释

Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名,而不是仅仅将键名重新排序。

Note: Like most PHP sorting functions, sort() uses an implementation of » Quicksort.

Warning

Be careful when sorting arrays with mixed types values because sort() can produce unpredictable results.

参见


数组 函数
在线手册:中文 英文
PHP手册
PHP手册 - N: 对数组排序

用户评论:

Adrian at xdt dot co dot uk (17-Mar-2012 10:12)

To holdoffhunger 02-Jan-2012:

Interesting approach you have there. How about this instead?

    <?php
   
function longestfirst($str1, $str2) {
    return
strlen($str2) - strlen($str1);
    }

    function
shortestFirst($str1, $str2) {
    return
strlen($str1) - strlen($str2);
    }

   
$data = array("hello", "12", "php", "is", "awesome", "1", "1234", "123");

   
uasort($data, 'longestFirst');
    echo
'<pre>';
   
print_r($data);

   
uasort($data, 'shortestFirst');
   
print_r($data);
    echo
'</pre>';

   
/* Gives you:
    Array (
    [4] => awesome
    [0] => hello
    [6] => 1234
    [2] => php
    [7] => 123
    [3] => is
    [1] => 12
    [5] => 1
    )
    Array (
    [5] => 1
    [3] => is
    [1] => 12
    [7] => 123
    [2] => php
    [6] => 1234
    [0] => hello
    [4] => awesome
    ) */

   
?>

The order is undefined where the strings have the same length.

Hope that helps.

holdoffhunger at gmail dot com (03-Jan-2012 01:02)

I wanted a function that would efficiently let me sort a string array by the length of each entry.  Below is a neat trick in logic that allows me to manipulate the sort function.  (1) Get the length of the string, (2) Str_pad the length with 0's, so that it is a definite length, (3) Append that number to the beginning of the string, (4) Then do rsort or sort normally.  Below is an rsort implementation...

<?php

   
// Released Under Affero General Public License, Version 3 (AGPL3)
    // Author: holdoffhunger@gmail.com

   
$array_of_data = array(        "hello",
                   
"php",
                   
"is",
                   
"awesome",
                   
"1",
                   
"1234",
                   
"12",
                   
"9");
   
    print(
"<pre>");               
   
print_r($array_of_data);
   
   
/*  Output Here Is:
            Array
        (
            [0] => hello
            [1] => php
            [2] => is
            [3] => awesome
            [4] => 1
            [5] => 1234
            [6] => 12
            [7] => 9
        )
    */
   
   
$number_of_entries = count($array_of_data);

    for(
$i = 0; $i < $number_of_entries; $i++)
    {
       
$current_entry = $array_of_data[$i];
       
$current_entry_length = strlen($current_entry);
       
$appendable_entry_length = str_pad($current_entry_length, 10, "0", STR_PAD_LEFT);
       
$array_of_data[$i] = $appendable_entry_length . " /|\/|\/|\ " . $array_of_data[$i];
    }
   
   
rsort($array_of_data);
   
    for(
$i = 0; $i < $number_of_entries; $i++)
    {
       
$current_entry = $array_of_data[$i];
       
$current_entry_explosion = explode(" /|\/|\/|\ ", $current_entry);
       
$array_of_data[$i] = $current_entry_explosion[1];
    }
   
   
print_r($array_of_data);
    print(
"</pre>");
   
   
/*  Sorted Output Here Is:
        Array
        (
            [0] => awesome
            [1] => hello
            [2] => 1234
            [3] => php
            [4] => is
            [5] => 12
            [6] => 9
            [7] => 1
        )
    */

?>

Walter Tross (16-Dec-2011 10:38)

unless you specify the second argument, "regular" comparisons will be used. I quote from the page on comparison operators:
"If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically."
What this means is that "10" < "1a", and "1a" < "2", but "10" > "2". In other words, regular PHP string comparisons are not transitive.
This implies that the output of sort() can in rare cases depend on the order of the input array:
<?php
function echo_sorted($a)
{
   echo
"{$a[0]} {$a[1]} {$a[2]}";
  
sort($a);
   echo
" => {$a[0]} {$a[1]} {$a[2]}\n";
}
// on PHP 5.2.6:
echo_sorted(array( "10", "1a", "2")); // => 10 1a 2
echo_sorted(array( "10", "2", "1a")); // => 1a 2 10
echo_sorted(array( "1a", "10", "2")); // => 2 10 1a
echo_sorted(array( "1a", "2", "10")); // => 1a 2 10
echo_sorted(array( "2", "10", "1a")); // => 2 10 1a
echo_sorted(array( "2", "1a", "10")); // => 10 1a 2
?>

ajanata at gmail dot com (21-Oct-2011 05:13)

This took me longer than it should have to figure out, but if you want the behavior of sort($array, SORT_STRING) (that is, re-indexing the array unlike natcasesort) in a case-insensitive manner, it is a simple matter of doing usort($array, strcasecmp).

holdoffhunger at gmail dot com (18-Jul-2011 05:14)

I have discovered an interesting trick with the sort function.  Many coders are using it to sort options for a user, because a computer will only need sorted data in limited cases.  However, every coder wants their sorted data to be usable.  It's very common to find any sorted data online, and to find options, "Sort by Date," "Sort Alphabetically," etc., etc., whether you're looking at an online catalogue or some bulletin board.

The trick is to use a combination of html commenting and str_pad's to do definitive "sort by" functions.  Let me demonstrate with an example: consider two arrays, Sorted_By_Date and Sorted_By_Name.  You want every element to be "<option value=something>Option Name</option", so that you can do a simple foreach statement that prints every option value.  But, sorting these arrays will technically sort just sort whatever you put into "value".  So, here's a neat trick.  Make every entry "<!-- Sort_Value --><option value=something>Option Name</option."  That way, when you sort, it'll have to sort technically by whatever is the Sort_Value.

The greatness of this trick is that you can make as many "sort this data by X" fields as you want!  Just create multiple arrays, each with the same option values and names, but with a different value put in "Sort_Value", which could be a date, a name, a price, etc..  With numbers, you may need to use the str_pad function, to push all of the zeros out to the left, for a proper sort.  For instance, in my code, that looks like...

<?php

                $number_of_versions_sort_value
= str_pad($number_of_versions, 20, "0", STR_PAD_LEFT);

?>

alex dot hristov dot 88 at gmail dot com (16-Jun-2011 03:26)

As some people have mentioned before sorting a multidimentional array can be a bit tricky. it took me quite a while to get it going but it works as a charm:

<?php
//$order has to be either asc or desc
 
function sortmulti ($array, $index, $order, $natsort=FALSE, $case_sensitive=FALSE) {
        if(
is_array($array) && count($array)>0) {
            foreach(
array_keys($array) as $key)
           
$temp[$key]=$array[$key][$index];
            if(!
$natsort) {
                if (
$order=='asc')
                   
asort($temp);
                else   
                   
arsort($temp);
            }
            else
            {
                if (
$case_sensitive===true)
                   
natsort($temp);
                else
                   
natcasesort($temp);
            if(
$order!='asc')
               
$temp=array_reverse($temp,TRUE);
            }
            foreach(
array_keys($temp) as $key)
                if (
is_numeric($key))
                   
$sorted[]=$array[$key];
                else   
                   
$sorted[$key]=$array[$key];
            return
$sorted;
        }
    return
$sorted;
}
?>

markrose at markrose dot ca (01-Jun-2011 07:54)

I've yet to come across a fast way to merge sorted arrays by a user value. Merging the arrays and using PHP's usort isn't efficient, as it doesn't take advantage of the existing sorting. So I wrote my own merge sorted arrays by user value function. The limit parameter can be used be used to limit the number of results (there is no point sorting more results than needed). This sort is stable: values will be taken preferentially from the first, then second, etc., array inside $merge_arrays.

Note that this function will fail if a user value is boolean false. It could be adapted to hold the best value inside an array at some performance penalty. It could also be adapted to comparing strings case-insensitively.

To give you some idea of the performance, my machine will sort out the first 1000 values of 10 sorted arrays of 1000 values each in under 40 ms, using an integer sort field. Not fast by C standards, but a vast improvement over usort'ing 10,000 values.

<?php
function merge_sorted_arrays_by_field ($merge_arrays, $sort_field, $sort_desc = false, $limit = 0)
{
   
$array_count = count($merge_arrays);
   
   
// fast special cases...
   
switch ($array_count)
    {
        case
0: return array();
        case
1: return $limit ? array_slice(reset($merge_arrays), 0, $limit) : reset($merge_arrays);
    }
   
    if (
$limit === 0)
       
$limit = PHP_INT_MAX;
   
   
// rekey merge_arrays array 0->N
   
$merge_arrays = array_values($merge_arrays);

   
$best_array = false;
   
$best_value = false;
   
   
$results = array();
   
   
// move sort order logic outside the inner loop to speed things up
   
if ($sort_desc)
    {
        for (
$i = 0; $i < $limit; ++$i)
        {
            for (
$j = 0; $j < $array_count; ++$j)
            {
               
// if the array $merge_arrays[$j] is empty, skip to next
               
if (false === ($current_value = current($merge_arrays[$j])))
                    continue;
               
               
// if we don't have a value for this round, or if the current value is bigger...
               
if ($best_value === false || $current_value[$sort_field] > $best_value[$sort_field])
                {
                   
$best_array = $j;
                   
$best_value = $current_value;
                }
            }
           
           
// all arrays empty?
           
if ($best_value === false)
                break;
           
           
$results[] = $best_value;
           
$best_value = false;
           
next($merge_arrays[$best_array]);
        }
    }
    else
    {
        for (
$i = 0; $i < $limit; ++$i)
        {
            for (
$j = 0; $j < $array_count; ++$j)
            {
                if (
false === ($current_value = current($merge_arrays[$j])))
                    continue;
               
               
// if we don't have a value for this round, or if the current value is smaller...
               
if ($best_value === false || $current_value[$sort_field] < $best_value[$sort_field])
                {
                   
$best_array = $j;
                   
$best_value = $current_value;
                }
            }
           
           
// all arrays empty?
           
if ($best_value === false)
                break;
           
           
$results[] = $best_value;
           
$best_value = false;
           
next($merge_arrays[$best_array]);
        }
    }
   
    return
$results;
}
?>

cmarshall at gmx dot de (17-May-2011 11:10)

I read up on various problems re: sort() and German Umlaut chars and my head was soon spinning - bug in sort() or not, solution via locale or not, etc. ... (a total newbie here).

The obvious solution for me was quick and dirty: transform the Umlaut chars (present as HTML codes in my case) to their normal equivalent ('?' = 'ae', '?' = 'oe', 'ü' = 'ue', '?' = 'ss' etc.), sort the array, then transform back. However there are cases in which a 'Mueller' is really that and does NOT need to be transformed into 'Müller' afterwards. Hence I for example replace the Umlaut itself with it's normal equivalent plus a char not used in the string otherwise (e.g. '_') so that the transfer back to Umlaut would only take place on certain combinations.

Of course any other char instead of '_' can be used as additional char (influencing the sort result). I know that my solution is rough at the edges and may cause other sort problems but it was sufficient for my purpose.

The array '$dat' in this example was filled with German town names (I actually worked with a multiple array ('$dat[][]') but stripped the code down to this as it's easier to understand):

<?php
// START Pre-sorting (Umlaut -> normal letters)
$max = count($dat);
for(
$totcnt = 0; $totcnt < $max; $totcnt++){
  
$dat[$totcnt]=str_replace('&szlig;','ss_',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('&Auml;','Ae_',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('&auml;','ae_',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('&Ouml;','Oe_',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('&ouml;','oe_',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('&Uuml;','Ue_',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('&uuml;','ue_',$dat[$totcnt]);
}
// END Pre-sorting (Umlaut -> normal letters)

// START Sorting //
function compare_towns($a, $b)
{
return
strnatcmp($a, $b);
}
usort($dat, 'compare_towns');
// END Sorting //

// START Post-sorting (normal letters -> Umlaut)
for($totcnt = 0; $totcnt < $max; $totcnt++){
  
$dat[$totcnt]=str_replace('ss_','&szlig;',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('Ae_','&Auml;',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('ae_','&auml;',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('Oe_','&Ouml;',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('oe_','&ouml;',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('Ue_','&Uuml;',$dat[$totcnt]);
  
$dat[$totcnt]=str_replace('ue_','&uuml;',$dat[$totcnt]);
}
// END Post-sorting (normal letters -> Umlaut)
?>

anaz114119 at gmail dot com (24-Dec-2010 10:34)

sort from textfile by coloumn
example name||date||time||comments
if you want to sort by date
$column = 2
<?php
function array_sort($array,$column){
 
$column = $column-1;
 foreach(
$array as $line){
 
$bits = explode("||",$line);
 
$bits ="$bits[$column]**$line";
 
$array1[]=$bits;
}
 
asort($array1);
 foreach(
$array1 as $line){
 
$bit = explode("**",$line);
 
$bit ="$bit[1]";
 
$array2[]=$bit;
}
 return
$array2;
}
?>

poulou_0 at hotmail dot com (21-Dec-2010 08:59)

if you are not interested in high or low case sort

<?php
//where
$sortable_array[$k] = $v2;
//put
$sortable_array[$k] = strtolower($v2);

//and where
$sortable_array[$k] = $v;
//put
$sortable_array[$k] = strtolower($v);
?>

phpdotnet at m4tt dot co dot uk (16-Aug-2010 03:03)

Simple function to sort an array by a specific key. Maintains index association.

<?php

function array_sort($array, $on, $order=SORT_ASC)
{
   
$new_array = array();
   
$sortable_array = array();

    if (
count($array) > 0) {
        foreach (
$array as $k => $v) {
            if (
is_array($v)) {
                foreach (
$v as $k2 => $v2) {
                    if (
$k2 == $on) {
                       
$sortable_array[$k] = $v2;
                    }
                }
            } else {
               
$sortable_array[$k] = $v;
            }
        }

        switch (
$order) {
            case
SORT_ASC:
               
asort($sortable_array);
            break;
            case
SORT_DESC:
               
arsort($sortable_array);
            break;
        }

        foreach (
$sortable_array as $k => $v) {
           
$new_array[$k] = $array[$k];
        }
    }

    return
$new_array;
}

$people = array(
   
12345 => array(
       
'id' => 12345,
       
'first_name' => 'Joe',
       
'surname' => 'Bloggs',
       
'age' => 23,
       
'sex' => 'm'
   
),
   
12346 => array(
       
'id' => 12346,
       
'first_name' => 'Adam',
       
'surname' => 'Smith',
       
'age' => 18,
       
'sex' => 'm'
   
),
   
12347 => array(
       
'id' => 12347,
       
'first_name' => 'Amy',
       
'surname' => 'Jones',
       
'age' => 21,
       
'sex' => 'f'
   
)
);

print_r(array_sort($people, 'age', SORT_DESC)); // Sort by oldest first
print_r(array_sort($people, 'surname', SORT_ASC)); // Sort by surname

/*
Array
(
    [12345] => Array
        (
            [id] => 12345
            [first_name] => Joe
            [surname] => Bloggs
            [age] => 23
            [sex] => m
        )
 
    [12347] => Array
        (
            [id] => 12347
            [first_name] => Amy
            [surname] => Jones
            [age] => 21
            [sex] => f
        )
 
    [12346] => Array
        (
            [id] => 12346
            [first_name] => Adam
            [surname] => Smith
            [age] => 18
            [sex] => m
        )
 
)
Array
(
    [12345] => Array
        (
            [id] => 12345
            [first_name] => Joe
            [surname] => Bloggs
            [age] => 23
            [sex] => m
        )
 
    [12347] => Array
        (
            [id] => 12347
            [first_name] => Amy
            [surname] => Jones
            [age] => 21
            [sex] => f
        )
 
    [12346] => Array
        (
            [id] => 12346
            [first_name] => Adam
            [surname] => Smith
            [age] => 18
            [sex] => m
        )
 
)
*/

?>

eriewave at hotmail dot com (29-Mar-2010 09:16)

If you need to sort an array containing some equivalent values and you want the equivalents to end up next to each other in the overall order (similar to a MySQL's ORDER BY output), rather than breaking the function, do this:

<?php

sort
($array, ksort($array))

?>

-When the sort() function finds two equivalents, it will sort them arbitrarily by their key #'s as a second parameter.

-Dirk

Dollar Hauler Admin (12-Mar-2010 06:10)

I could never find a way to sort multidimensional arrays with 5+ keys while maintaining the data structure, but here it is:

(you can add an infinite number of keys, but it has to be added manually :\ )

<?php

$array
[0]['name']  = 'Chris';
$array[0]['phone'] = '3971095';
$array[0]['year']  = '1978';
$array[0]['address'] = 'Street 1';

$array[1]['name']  = 'Breanne';
$array[1]['phone'] = '3766350';
$array[1]['year']  = '1990';
$array[1]['address'] = 'Street 2';

$array[2]['name']  = 'Dusty';
$array[2]['phone'] = '1541120';
$array[2]['year']  = '1982';
$array[2]['address'] = 'Street 3';

function
multisort($array, $sort_by, $key1, $key2=NULL, $key3=NULL, $key4=NULL, $key5=NULL, $key6=NULL){
   
// sort by ?
   
foreach ($array as $pos =>  $val)
       
$tmp_array[$pos] = $val[$sort_by];
   
asort($tmp_array);
   
   
// display however you want
   
foreach ($tmp_array as $pos =>  $val){
       
$return_array[$pos][$sort_by] = $array[$pos][$sort_by];
       
$return_array[$pos][$key1] = $array[$pos][$key1];
        if (isset(
$key2)){
           
$return_array[$pos][$key2] = $array[$pos][$key2];
            }
        if (isset(
$key3)){
           
$return_array[$pos][$key3] = $array[$pos][$key3];
            }
        if (isset(
$key4)){
           
$return_array[$pos][$key4] = $array[$pos][$key4];
            }
        if (isset(
$key5)){
           
$return_array[$pos][$key5] = $array[$pos][$key5];
            }
        if (isset(
$key6)){
           
$return_array[$pos][$key6] = $array[$pos][$key6];
            }
        }
    return
$return_array;
    }

//usage (only enter the keys you want sorted):

$sorted = multisort($array,'year','name','phone','address');
print_r($sorted);

//output:
Array ( [0] => Array ( [year] => 1978 [name] => Chris [phone] => 3971095 [address] => Street 1 ) [2] => Array ( [year] => 1982 [name] => Dusty [phone] => 1541120 [address] => Street 3 ) [1] => Array ( [year] => 1990 [name] => Breanne [phone] => 3766350 [address] => Street 2 ) )

Brecht Cloetens (23-Nov-2009 11:57)

<?php
   
/**
 * function: array_columns
 * author: Brecht Cloetens
 * params: $a = array() // original array
 *         $c = int() // number of columns
 */
function array_columns(&$a, $c=2)
{
   
$m = ceil(count($a)/$c);
   
$j = 0;
    for(
$i=0; $i<$m; $i++) {
        for(
$k=0; $k<$c; $k++) {
           
$key = $i+($m*$k);
           
settype($key,'integer');
            if(
array_key_exists($key,$a)) {
               
$b[$j] = $a[$key];
               
$j++;
            }
        }
    }
   
$a = $b;
}

$arr = range('a','z');
array_columns($arr,4);
print_r($arr);

?>

Example:
array(1,2,3,4,5) will be converted to array(1,4,2,5,3);

This can be easy if you want to display an array into a specified number of columns.

<table>
    <tr>
        <td>$arr[0] => 1</td>
        <td>$arr[1] => 4</td>
    </tr>
    <tr>
        <td>$arr[2] => 2</td>
        <td>$arr[3] => 5</td>
    </tr>
    <tr>
        <td>$arr[4] => 3</td>
        <td></td>
    </tr>
</table>

Anonymous (17-Nov-2009 02:10)

[EDIT BY danbrown AT php DOT net: The code provided by this anonymous author contains bugfixes for and additions to code originally donated by "toenie" on 07-NOV-09.  The original author included the following note: "If you want to sort while using an 2 dimensional array, you can use this script I just wrote for myself. I thought it could be helpful for other people too."]

I also added the ability to sort in ascending and descending order.

$order = "ASC" will sort the array in ascending order
$order = "DESC" will sort the array in descending order

Here is the code:

<?php
   
function order_array_num ($array, $key, $order = "ASC")
    {
       
$tmp = array();
        foreach(
$array as $akey => $array2)
        {
           
$tmp[$akey] = $array2[$key];
        }
       
        if(
$order == "DESC")
        {
arsort($tmp , SORT_NUMERIC );}
        else
        {
asort($tmp , SORT_NUMERIC );}

       
$tmp2 = array();       
        foreach(
$tmp as $key => $value)
        {
           
$tmp2[$key] = $array[$key];
        }       
       
        return
$tmp2;
    }
?>

petr dot biza at gmail dot com (11-Sep-2009 02:29)

Here is a function to sort an array by the key of his sub-array with keep key in top level.

<?php
function sksort(&$array, $subkey="id", $sort_descending=false, $keep_keys_in_sub = false) {
   
$temp_array = $array;

    foreach (
$temp_array as $key => &$value) {
     
     
$sort = array();
      foreach (
$value as $index => $val) {
         
$sort[$index] = $val[$subkey];
      }
     
     
asort($sort);
     
     
$keys = array_keys($sort);
     
$newValue = array();
      foreach (
$keys as $index) {
        if(
$keep_keys_in_sub)
           
$newValue[$index] = $value[$index];
          else
           
$newValue[] = $value[$index];
      }
     
      if(
$sort_descending)
       
$value = array_reverse($newValue, $keep_keys_in_sub);
      else
       
$value = $newValue;
    }
   
   
$array = $temp_array;
  }
?>

phpnet at theindy dot net (27-Aug-2009 06:45)

In response to the msort function I find that the array_multisort function is a lot faster.

-John

danm68 at gmail dot com (26-Aug-2009 05:59)

sort() used with strings doesn't sort just alphabetically. It sorts all upper-case strings alphabetically first and then sorts lower-case strings alphabetically second.
Just in case anyone was as confused as I was and I've never seen this mentioned anywhere.

otobrglez at gmail dot com (18-Feb-2009 08:45)

This will select number of unique keys from array and order them in original order.

<?php
/*
$rows - array of records
$st - number of keys that you want to have

By Oto Brglez.

*/

$pom_k = array();
for(
$i=0; $i<$st;){
   
$pom = array_rand($rows,1);
    if(!
in_array($pom,$pom_k)){
       
$pom_k[] = $pom;
       
$i++;
    };
};
sort($pom_k,SORT_NUMERIC);

?>

stepmuel at ee dot ethz dot ch (10-Dec-2008 04:14)

A little shorter way to sort an array of objects; with a callback function.

<?php
function objSort(&$objArray,$indexFunction,$sort_flags=0) {
   
$indices = array();
    foreach(
$objArray as $obj) {
       
$indeces[] = $indexFunction($obj);
    }
    return
array_multisort($indeces,$objArray,$sort_flags);
}

function
getIndex($obj) {
    return
$obj->getPosition();
}

objSort($objArray,'getIndex');
?>

jalil at measat dot org (15-Nov-2008 09:48)

this is an implementation of the complement of
Matthew Hood's objectSort (http://my.php.net/manual/en/function.sort.php#75036), which i found very convenient for sorting objects.

this does the reverse, it sorts according to the key
selected for the object but in reverse order.
and having both sort methods allows consistency and convenience for sorting objects, if speed isn't your major concern.

the only change ( apart form data being reworded as object )  is the use of < instead of > in the original.
you could of couse incorporate all in one routine, but why
complicate matters.

<?php
   
function objectRSort(&$object, $key)
    {
        for (
$i = count($object) - 1; $i >= 0; $i--)
        {
         
$swapped = false;
          for (
$j = 0; $j < $i; $j++)
          {
               if (
$object[$j]->$key < $object[$j + 1]->$key)
               {
                   
$tmp = $object[$j];
                   
$object[$j] = $object[$j + 1];      
                   
$object[$j + 1] = $tmp;
                   
$swapped = true;
               }
          }
          if (!
$swapped) return;
        }
    }
?>

lucazd at gmail dot com (26-Sep-2008 09:04)

Please, think twice before creating (and posting) your homemade solution for ordering an array by a field.

PHP already has a solution for this; usort, which is about x40 faster than any other solution.

If creating a callback for each case hurts, you can do something like this:

<?php
/**
 * @author Lucas Dománico
 */
class util {
    static private
$sortfield = null;
    static private
$sortorder = 1;
    static private function
sort_callback(&$a, &$b) {
        if(
$a[self::$sortfield] == $b[self::$sortfield]) return 0;
        return (
$a[self::$sortfield] < $b[self::$sortfield])? -self::$sortorder : self::$sortorder;
    }
    static function
sort(&$v, $field, $asc=true) {
       
self::$sortfield = $field;
       
self::$sortorder = $asc? 1 : -1;
       
usort($v, array('util', 'sort_callback'));
    }
}

# Usage:
for($i=0; $i<1000 ;$i++) {
 
$v[] = array('score'=>rand(1,10000));
}
util::sort($v, 'score');

?>

www at designdetector dot com (09-Sep-2008 03:43)

To sort an array of multiple text fields alphabetically you have to make the text lowercase before sorting the array. Otherwise PHP puts acronyms before words. You can see this in my example code. Simply store the original text field at the end of the array line and call it later from there. You can safely ignore the lowercase version which is added to the start of the array line.

<?php
echo '<pre>ORIGINAL DATA:
<br />'
;

$data = array(
'Saturn|7|8|9|0||',
'Hello|0|1|2|3||',
'SFX|5|3|2|4||',
'HP|9|0|5|6||'
);

print_r($data);

sort($data);
reset($data);

echo
'<br />RAW SORT:
<br />'
;

print_r($data);

for (
$c = 0; $c < count($data); $c++) {
    list (
$letter,$g1,$g2,$g3,$g4,$end) = explode ('|', $data[$c]);
   
$lowercase = strtolower($letter);
   
$data2[$c] = array($lowercase,$g1,$g2,$g3,$g4,$letter);
}

sort($data2);
reset($data2);

echo
'<br />LOWERCASE SORT:
<br />'
;

print_r($data2);

echo
'</pre>';
?>

matpatnik at hotmail dot com (23-Jan-2008 11:46)

This function will sort entity letters eg:&eacute;

I hope that help someone

function sort_entity($array) {
    $total = count($array);
    for ($i=0;$i<$total;$i++) {
        if ($array[$i]{0} == '&') {
            $array[$i] = $array[$i]{1}.$array[$i];
        } else {
            $array[$i] = $array[$i]{0}.$array[$i];
        }
    }
    sort($array);
   
    for ($i=0;$i<$total;$i++) {
        $array[$i] = substr($array[$i],1);
    }
   
    return $array;
}

jasons at work dot com (07-Jan-2008 08:25)

Update to the msort code posted by: alishahnovin

I had a problem with the msort function not being case sensitive. All capital letters A-Z would list in order then all lowercase letters would follow.

the line:
if ($item[$id]<$array[$lowest_id][$id]) {

was changed to:
if (strtolower($item[$id]) < strtolower($array[$lowest_id][$id])) {

<?php
function msort($array, $id="id", $sort_ascending=true) {
       
$temp_array = array();
        while(
count($array)>0) {
           
$lowest_id = 0;
           
$index=0;
            foreach (
$array as $item) {
                if (isset(
$item[$id])) {
                                    if (
$array[$lowest_id][$id]) {
                    if (
strtolower($item[$id]) < strtolower($array[$lowest_id][$id])) {
                       
$lowest_id = $index;
                    }
                    }
                                }
               
$index++;
            }
           
$temp_array[] = $array[$lowest_id];
           
$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
        }
                if (
$sort_ascending) {
            return
$temp_array;
                } else {
                    return
array_reverse($temp_array);
                }
    }
?>

david wh thomas at gm at 1l dot c0m (03-Sep-2007 02:02)

Here's a variation on the above function to sort arrays with more than one key by an arbitrary key's value.

This function allows sorting of an array of objects too

<?php
   
/**
     * Sorts an array of objects by the value of one of the object properties or array keys
     *
     * @param array $array
     * @param key value $id
     * @param boolean $sort_ascending
     * @param boolean $is_object_array
     * @return array
     */
 
function vsort($array, $id="id", $sort_ascending=true, $is_object_array = false) {
       
$temp_array = array();
        while(
count($array)>0) {
           
$lowest_id = 0;
           
$index=0;
            if(
$is_object_array){
                foreach (
$array as $item) {
                    if (isset(
$item->$id)) {
                                        if (
$array[$lowest_id]->$id) {
                        if (
$item->$id<$array[$lowest_id]->$id) {
                           
$lowest_id = $index;
                        }
                        }
                                    }
                   
$index++;
                }
            }else{
                foreach (
$array as $item) {
                    if (isset(
$item[$id])) {
                        if (
$array[$lowest_id][$id]) {
                        if (
$item[$id]<$array[$lowest_id][$id]) {
                           
$lowest_id = $index;
                        }
                        }
                                    }
                   
$index++;
                }                             
            }
           
$temp_array[] = $array[$lowest_id];
           
$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
        }
                if (
$sort_ascending) {
            return
$temp_array;
                } else {
                    return
array_reverse($temp_array);
                }
    }

?>

Sample Usage:

<?php
$nodes
= vsort($nodes,'term_data_weight', false, true);
print
'<pre>'.print_r($nodes,1).'</pre>';
?>

quirk at qns dot se (22-Jul-2007 01:42)

Hi, this is my version of sorting an array by field.

From browsing previous versions it pretty much resembles bluej's version. It's way much faster than the versions where the sorting is made "manually" rather than with native php functions, and I wrote it after trying one of those that kept timing out my scripts if I had 10000 posts.

This one preserves numerical keys as well. So if you want to re-index the array after using it with numerical keys just use the array_values on the result. However there are cases where the key actually means something even if it's a number (id etc) so I didn't want to take it for granted that it should be reindexed.

Cheers
Q

<?php
       
function sortArrayByField
       
(
           
$original,
           
$field,
           
$descending = false
       
)
        {
           
$sortArr = array();
           
            foreach (
$original as $key => $value )
            {
               
$sortArr[ $key ] = $value[ $field ];
            }
   
            if (
$descending )
            {
               
arsort( $sortArr );
            }
            else
            {
               
asort( $sortArr );
            }
           
           
$resultArr = array();
            foreach (
$sortArr as $key => $value )
            {
               
$resultArr[ $key ] = $original[ $key ];
            }
       
            return
$resultArr;
        }           
?>

alishahnovin at hotmail dot com (20-Jul-2007 12:16)

Someone asked me if the msort I posted below can do a sort by descending... (as it sorts by ascending...smallest to greatest).

It's a simple fix with an extra param, and then an array_reverse...but for the lazy, here you are:

<?php
function msort($array, $id="id", $sort_ascending=true) {
       
$temp_array = array();
        while(
count($array)>0) {
           
$lowest_id = 0;
           
$index=0;
            foreach (
$array as $item) {
                if (isset(
$item[$id])) {
                                    if (
$array[$lowest_id][$id]) {
                    if (
$item[$id]<$array[$lowest_id][$id]) {
                       
$lowest_id = $index;
                    }
                    }
                                }
               
$index++;
            }
           
$temp_array[] = $array[$lowest_id];
           
$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
        }
                if (
$sort_ascending) {
            return
$temp_array;
                } else {
                    return
array_reverse($temp_array);
                }
    }
?>

<?php

//oh no, this is not in the ordered by id!!
$data[] = array("item"=>"item 1", "id"=>1);
$data[] = array("item"=>"item 3", "id"=>3);
$data[] = array("item"=>"item 2", "id"=>2);

var_dumpmsort($data, "id", false)  ); //just msort it...greatest to smallest

var_dumpmsort($data, "id")  ); //just msort it...smallest to greatest

/* outputs

array
  0 =>
    array
      'item' => 'item 3' (length=6)
      'id' => 3
  1 =>
    array
      'item' => 'item 2' (length=6)
      'id' => 2
  2 =>
    array
      'item' => 'item 1' (length=6)
      'id' => 1

array
  0 =>
    array
      'item' => 'item 1' (length=6)
      'id' => 1
  1 =>
    array
      'item' => 'item 2' (length=6)
      'id' => 2
  2 =>
    array
      'item' => 'item 3' (length=6)
      'id' => 3

*/

?>

bluej100@gmail (10-Jul-2007 11:03)

The sort2d I posted before did nothing by default--that'll teach me to copy-and-paste without thinking. Its sort function has to be associative. I've changed the default to asort. natcasesort does actually work, though.

// $sort used as variable function--can be natcasesort, for example
// WARNING: $sort must be associative
function sort2d( &$arrIn, $index = null, $sort = 'asort') {
  // pseudo-secure--never allow user input into $sort
  if (strpos($sort, 'sort') === false) {$sort = 'asort';}
  $arrTemp = Array();
  $arrOut = Array();

  foreach ( $arrIn as $key=>$value ) {
    $arrTemp[$key] = is_null($index) ? reset($value) : $value[$index];
  }

  $sort($arrTemp);

  foreach ( $arrTemp as $key=>$value ) {
    $arrOut[$key] = $arrIn[$key];
  }

  $arrIn = $arrOut;
}

Also, uasort is probably actually the better solution for most 2d sorting, unless you're sorting by a dozen different indexes.

NBS Studio (04-Jul-2007 09:14)

This is my way of sorting files into date modified date order. It worked for me!

$dir='topics';
$ext='php5';
$files=scandir($dir);
foreach($files as $fs){
    if(($fs!='.')&&($fs!='..')){
        $fs1.='?'.filemtime($dir.'/'.$fs).'#'.$fs;
    }
}
$fs2=split('[?]',$fs1);
arsort($fs2);
foreach($fs2 as $fs3){
    if(eregi($ext,$fs3)){
        $fs4.='?'.$fs3;
    }
}
$fs5=split('[#]',$fs4);
foreach($fs5 as $fs6){
    if(eregi($ext,$fs6)){
        $fs7.='?'.$fs6;
    }
}
$fs8=split('[?]',$fs7);
foreach($fs8 as $fs9){
    $file_list.=$fs9.'
</br>';
}

print $file_list;

sinan at sinaneldem dot com (24-Jun-2007 04:29)

here is little script which will merge arrays, remove duplicates and sort it by alphabetical order:

<?php

$array1
= array('apple', 'banana','pear');
$array2 = array('grape', 'pear','orange');

function
array_unique_merge_sort($array1, $array2){
$array = array_unique(array_merge($array1, $array2));
sort($array);
foreach (
$array as $key => $value) {
   
$new[$key] = $value;
}
return
$new;
}

print_r (array_unique_merge_sort($array1, $array2));

?>

this will print out:

Array ( [0] => apple [1] => banana [2] => grape [3] => orange [4] => pear )

bluej100@gmail (07-Jun-2007 11:05)

One more solution for multidimensional sort: variable functions.

<?php
// $sort used as variable function--can be natcasesort, for example
 
function sort2d( &$arrIn, $index = null, $sort = 'sort') {
   
// pseudo-secure--never allow user input into $sort
   
if (strpos($sort, 'sort') === false) {$sort = 'sort';}
   
$arrTemp = Array();
   
$arrOut = Array();

    foreach (
$arrIn as $key=>$value ) {
     
reset($value);
     
$arrTemp[$key] = is_null($index) ? current($value) : $value[$index];
    }

   
$sort($arrTemp);

    foreach (
$arrTemp as $key=>$value ) {
     
$arrOut[$key] = $arrIn[$key];
    }

   
$arrIn = $arrOut;
  }
?>

It appears to me that there are only two algorithms being proposed here (several times each):

1) copy into temp, pass temp to sort function, re-order by temp
2) implement search function in PHP

I'm curious whether anyone's implementation of (2) can beat (1) for speed. Someone have a fast PHP mergesort they can benchmark against this one? Obviously, the fact that the (1) solutions use at least two, possibly three times the memory is a drawback, but I expect that for most of us, speed is significantly more important than memory. Maybe I'll check it myself when I have a minute.

alishahnovin at hotmail dot com (28-May-2007 06:29)

Here's my fixed up msort array. What it does is goes through a multidimensional array, and sorts it by the desired key (defaulting to 'id').

So, for example, if you have an array like:

array[0]['value'] = "statement 2"
array[0]['id'] = "2"
array[1]['value'] = "statement 3"
array[1]['id'] = "3"
array[2]['value'] = "statement 1"
array[2]['id'] = "1"

it would rearrange and return the array to be like:

array[0]['value'] = "statement 1"
array[0]['id'] = "1"
array[1]['value'] = "statement 2"
array[1]['id'] = "2"
array[2]['value'] = "statement 3"
array[2]['id'] = "3"

The 'id' index can start at any point, and any array item missing the id index will be added to the end.

<?php
function msort($array, $id="id") {
       
$temp_array = array();
        while(
count($array)>0) {
           
$lowest_id = 0;
           
$index=0;
            foreach (
$array as $item) {
                if (isset(
$item[$id]) && $array[$lowest_id][$id]) {
                    if (
$item[$id]<$array[$lowest_id][$id]) {
                       
$lowest_id = $index;
                    }
                }
               
$index++;
            }
           
$temp_array[] = $array[$lowest_id];
           
$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
        }
        return
$temp_array;
    }
?>

Ex:

<?php

//oh no, this is not in the ordered by id!!
$data[] = array("item"=>"item 4");
$data[] = array("item"=>"item 1", "id"=>1);
$data[] = array("item"=>"item 3", "id"=>3);
$data[] = array("item"=>"item 2", "id"=>2);

var_dumpmsort($data)  ); //just msort it!

/* outputs

array
  0 =>
    array
      'item' => 'item 1' (length=6)
      'id' => 1
  1 =>
    array
      'item' => 'item 2' (length=6)
      'id' => 2
  2 =>
    array
      'item' => 'item 3' (length=6)
      'id' => 3
  3 =>
    array
      'item' => 'item 4' (length=6)

*/

?>

alishahnovin at hotmail dot com (26-May-2007 12:11)

I had a multidimensional array, which needed to be sorted by one of the keys. This is what I came up with...

<?php
function msort($array, $id="id") {
       
$temp_array = array();
        while(
count($array)>0) {
           
$lowest_id = 0;
           
$index=0;
            foreach (
$array as $item) {
                if (
$item[$id]<$array[$lowest_id][$id]) {
                   
$lowest_id = $index;
                }
               
$index++;
            }
           
$temp_array[] = $array[$lowest_id];
           
$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
        }
        return
$temp_array;
    }
?>

Ex:

<?php

//oh no, this is not in the ordered by id!!
$data[] = array("item"=>"item 4", "id"=>4);
$data[] = array("item"=>"item 1", "id"=>1);
$data[] = array("item"=>"item 3", "id"=>3);
$data[] = array("item"=>"item 2", "id"=>2);

var_dumpmsort($data)  ); //just msort it!

/* outputs

array
  0 =>
    array
      'item' => 'item 1' (length=6)
      'id' => 1
  1 =>
    array
      'item' => 'item 2' (length=6)
      'id' => 2
  2 =>
    array
      'item' => 'item 3' (length=6)
      'id' => 3
  3 =>
    array
      'item' => 'item 4' (length=6)
      'id' => 4

*/

?>

(Qube#php@Efnet) (14-May-2007 11:38)

How to use an anonymous array to sort any associative array by an arbitrary key (or nested key):

$order = -1; # -1 = Ascending. Use 1 for descending.
$sortby = "['key1']['subkey']";
$mysort = create_function('$a,$b', "\$a1=\$a$sortby;\$b1=\$b$sortby; if (\$a1==\$b1) return 0; else return (\$a1<\$b1) ? $order : 0- $
order;");
uasort($assocarray, $mysort);

You can use this in a recursive function if necessary (which is why I developed it).

Matthew Hood (09-May-2007 03:27)

The bubble sort below will sort an array of objects based on any one of the values contained in them.

usage: objectSort($details, 'percent');

function objectSort(&$data, $key)
{
    for ($i = count($data) - 1; $i >= 0; $i--)
    {
      $swapped = false;
      for ($j = 0; $j < $i; $j++)
      {
           if ($data[$j]->$key > $data[$j + 1]->$key)
           {
                $tmp = $data[$j];
                $data[$j] = $data[$j + 1];       
                $data[$j + 1] = $tmp;
                $swapped = true;
           }
      }
      if (!$swapped) return;
    }
}

y5 at yellow5 dot us (15-Mar-2007 02:52)

An improvement on the very nice code submitted by alex [at] vkpb [dot] com. This will preserve the keys if the array is numeric:

function SortDataSet($aArray, $sField, $bDescending = false)
{
    $bIsNumeric = IsNumeric($aArray);
    $aKeys = array_keys($aArray);
    $nSize = sizeof($aArray);

    for ($nIndex = 0; $nIndex < $nSize - 1; $nIndex++)
    {
        $nMinIndex = $nIndex;
        $objMinValue = $aArray[$aKeys[$nIndex]][$sField];
        $sKey = $aKeys[$nIndex];

        for ($nSortIndex = $nIndex + 1; $nSortIndex < $nSize; ++$nSortIndex)
        {
            if ($aArray[$aKeys[$nSortIndex]][$sField] < $objMinValue)
            {
                $nMinIndex = $nSortIndex;
                $sKey = $aKeys[$nSortIndex];
                $objMinValue = $aArray[$aKeys[$nSortIndex]][$sField];
            }
        }

        $aKeys[$nMinIndex] = $aKeys[$nIndex];
        $aKeys[$nIndex] = $sKey;
    }

    $aReturn = array();
    for($nSortIndex = 0; $nSortIndex < $nSize; ++$nSortIndex)
    {
        $nIndex = $bDescending ? $nSize - $nSortIndex - 1: $nSortIndex;
        $aReturn[$aKeys[$nIndex]] = $aArray[$aKeys[$nIndex]];
    }

    return $bIsNumeric ? array_values($aReturn) : $aReturn;
}

function IsNumeric($aArray)
{
    $aKeys = array_keys($aArray);
    for ($nIndex = 0; $nIndex < sizeof($aKeys); $nIndex++)
    {
        if (!is_int($aKeys[$nIndex]) || ($aKeys[$nIndex] != $nIndex))
        {
            return false;
        }
    }

    return true;
}

joris at mangrove dot nl (01-Feb-2007 01:40)

Commenting on note http://www.php.net/manual/en/function.sort.php#62311 :

Sorting an array of objects will not always yield the results you desire.

As pointed out correctly in the note above, sort() sorts the array by value of the first member variable. However, you can not always assume the order of your member variables! You must take into account your class hierarchy!

By default, PHP places the inherited member variables on top, meaning your first member variable is NOT the first variable in your class definition!
However, if you use code analyzers or a compile cache, things can be very different. E.g., in eAccelerator, the inherited member variables are at the end, meaning you get different sort results with caching on or off.

Conclusion:
Never use sort on arrays with values of a type other than scalar or array.

alex [at] vkpb [dot] com (26-Jan-2007 11:36)

Sorting of an array by a method of inserts.

<?

 
       function sortByField($multArray,$sortField,$desc=true){
            $tmpKey='';
            $ResArray=array();

            $maIndex=array_keys($multArray);
            $maSize=count($multArray)-1;

            for($i=0; $i < $maSize ; $i++) {

               $minElement=$i;
               $tempMin=$multArray[$maIndex[$i]][$sortField];
               $tmpKey=$maIndex[$i];

                for($j=$i+1; $j <= $maSize; $j++)
                  if($multArray[$maIndex[$j]][$sortField] < $tempMin ) {
                     $minElement=$j;
                     $tmpKey=$maIndex[$j];
                     $tempMin=$multArray[$maIndex[$j]][$sortField];

                  }
                  $maIndex[$minElement]=$maIndex[$i];
                  $maIndex[$i]=$tmpKey;
            }

           if($desc)
               for($j=0;$j<=$maSize;$j++)
                  $ResArray[$maIndex[$j]]=$multArray[$maIndex[$j]];
           else
              for($j=$maSize;$j>=0;$j--)
                  $ResArray[$maIndex[$j]]=$multArray[$maIndex[$j]];

           return $ResArray;
       }

// make array
$array['aaa']=array("name"=>"vasia","order"=>1);
$array['bbb']=array("name"=>"petia","order"=>2);
$array['ccc']=array("name"=>"kolia","order"=>3);
$array['ddd']=array("name"=>"zenia","order"=>4);

// set sort
$SortOrder=0; // desc by default , 1- asc

var_dump(sortByField($array,'order',$SortOrder));

array
  'ddd' =>
    array
      'name' => 'zenia' (length=5)
      'order' => 4
  'aaa' =>
    array
      'name' => 'vasia' (length=5)
      'order' => 1
  'bbb' =>
    array
      'name' => 'petia' (length=5)
      'order' => 2
  'ccc' =>
    array
      'name' => 'kolia' (length=5)
      'order' => 3

?>

crudo at pinknet dot cz (28-Nov-2006 01:54)

Simple way, how to sort an array without loosing keys:

<?php

$sizes
= $bad = $good = array("d" => "dddd", "a" => "aaaa", "c" => "cccc", "e" => "eeee", "b" => "bbbb");

// original
print_r($sizes);

/*
Array
(
    [d] => dddd
    [a] => aaaa
    [c] => cccc
    [e] => eeee
    [b] => bbbb
)
*/

// bad way
sort($bad);
print_r($bad);

/*
Array
(
    [0] => aaaa
    [1] => bbbb
    [2] => cccc
    [3] => dddd
    [4] => eeee
)
*/

// good way
$good=array_flip($good);
ksort($good);
$good=array_flip($good);

print_r($good);

/*
Array
(
    [a] => aaaa
    [b] => bbbb
    [c] => cccc
    [d] => dddd
    [e] => eeee
)
*/

?>

eran dot liberty at gmail dot com (15-Nov-2006 03:24)

/**
 * Will sort an array by the value of the applied lambda function to each element
 * without loosing the keys!
 * @param unknown_type $arr
 * @param unknown_type $func of the form mixvar func(your object)
 */
function sortByFunc(&$arr, $func) {
        $tmpArr = array();
        foreach ($arr as $k => &$e) {
            $tmpArr[] = array('f' => $func($e), 'k' => $k, 'e' =>&$e);
        }
        sort($tmpArr);
        $arr = array();
        foreach($tmpArr as &$fke) {
            $arr[$fke['k']] = &$fke['e'];
        }
}

example:
$arr = array(
    1 => array('name' => 'eran', 'age' => 30),
    2 => array('name' => 'naama', 'age' => 29),
    3 => array('name' => 'a', 'age' => 11),
    4 => array('name' => 'b', 'age' => 51),
    5 => array('name' => 'z', 'age' => 5),
);
foreach($arr as $key => $val) {
    echo "<br> $key => (" . $val['name'] . " ," . $val['age'] . ")";
}
sortByFunc($arr,create_function('$element','return $element["age"];'));
echo "<br> now sorted:";
foreach($arr as $key => $val) {
    echo "<br> $key => (" . $val['name'] . " ," . $val['age'] . ")";
}
output:
1 => (eran ,30)
2 => (naama ,29)
3 => (a ,11)
4 => (b ,51)
5 => (z ,5)
now sorted:
5 => (z ,5)
3 => (a ,11)
2 => (naama ,29)
1 => (eran ,30)
4 => (b ,51)

memzap at gmail dot com (21-Jul-2006 06:31)

Here is how you would open a file, and put each line into an array. This sorts by the first field $title field.  The next thing I would like to figure out is how to do this same sort but with the ability to skip the first word of the title. Like if the title has an "a" or "the" it would skip that portion of the sort.

$currentfile = "file.txt";
$fp = fopen( $currentfile, "r" ) or die("Couldn't open $currentfile");
while ( ! feof( $fp ) ) {
    $line[] = fgets( $fp, 1024 );

    foreach ( $line as $newarray ) {
}
    $newline[] = trim($newarray);
    sort($newline);
    list($title1, $titleurl1, $rating1) = split ('\|',
$newline[0]);
    list($title2, $titleurl2, $rating2) = split ('\|',
$newline[1]);
    list($title3, $titleurl3, $rating3) = split ('\|',
$newline[2]);
    list($title4, $titleurl4, $rating4) = split ('\|',
$newline[3]);

g8z at yahoo dot com (15-Jul-2006 12:28)

<?php
/**
This sort function allows you to sort an associative array while "sticking" some fields.

$sticky_fields = an array of fields that should not be re-sorted. This is a method of achieving sub-sorts within contiguous groups of records that have common data in some fields.

For example:

$a = array();

$a []= array(
    'name'         => 'Sam',
    'age'         => 23,
    'hire_date'    => '2004-01-01'
);
$a []= array(
    'name'        => 'Sam',
    'age'        => 44,
    'hire_date'    => '2003-03-23'
);
$a []= array(
    'name'        => 'Jenny',
    'age'        => 20,
    'hire_date' => '2000-12-31'
);
$a []= array(
    'name'        => 'Samantha',
    'age'        => 50,
    'hire_date' => '2000-12-14'
);

$sticky_fields = array( 'name' );
print_r( stickysort( $a, 'age', DESC_NUM, $sticky_fields ) );

OUTPUT:

Array
(
    [0] => Array
        (
            [name] => Sam
            [age] => 44
            [hire_date] => 2003-03-23
        )
    [1] => Array
        (
            [name] => Sam
            [age] => 23
            [hire_date] => 2004-01-01
        )
    [2] => Array
        (
            [name] => Jenny
            [age] => 20
            [hire_date] => 2000-12-31
        )
    [3] => Array
        (
            [name] => Samantha
            [age] => 50
            [hire_date] => 2000-12-14
        )
)

Here's why this is the correct output - the "name" field is sticky, so it cannot change its sort order. Thus, the "age" field is only sorted as a sub-sort within records where "name" is identical. Thus, the "Sam" records are reversed, because 44 > 23, but Samantha remains at the bottom, even though her age is 50. This is a way of achieving "sub-sorts" and "sub-sub-sorts" (and so on) within records of identical data for specific fields.

Courtesy of the $5 Script Archive: http://www.tufat.com
**/

define( 'ASC_AZ', 1000 );
define( 'DESC_AZ', 1001 );
define( 'ASC_NUM', 1002 );
define( 'DESC_NUM', 1003 );

function
stickysort( $arr, $field, $sort_type, $sticky_fields = array() ) {
   
$i = 0;
    foreach (
$arr as $value) {
       
$is_contiguous = true;
        if(!empty(
$grouped_arr)) {
           
$last_value = end($grouped_arr[$i]);

            if(!(
$sticky_fields == array())) {
                foreach (
$sticky_fields as $sticky_field) {
                    if (
$value[$sticky_field] <> $last_value[$sticky_field]) {
                       
$is_contiguous = false;
                        break;
                    }
                }
            }
        }
        if (
$is_contiguous)
           
$grouped_arr[$i][] = $value;
        else
           
$grouped_arr[++$i][] = $value;
    }
   
$code = '';
    switch(
$sort_type) {
        case
ASC_AZ:
           
$code .= 'return strcasecmp($a["'.$field.'"], $b["'.$field.'"]);';
            break;
        case
DESC_AZ:
           
$code .= 'return (-1*strcasecmp($a["'.$field.'"], $b["'.$field.'"]));';
            break;
        case
ASC_NUM:
           
$code .= 'return ($a["'.$field.'"] - $b["'.$field.'"]);';
            break;
        case
DESC_NUM:
           
$code .= 'return ($b["'.$field.'"] - $a["'.$field.'"]);';
            break;
    }

   
$compare = create_function('$a, $b', $code);

    foreach(
$grouped_arr as $grouped_arr_key=>$grouped_arr_value)
       
usort ( $grouped_arr[$grouped_arr_key], $compare );

   
$arr = array();
    foreach(
$grouped_arr as $grouped_arr_key=>$grouped_arr_value)
        foreach(
$grouped_arr[$grouped_arr_key] as $grouped_arr_arr_key=>$grouped_arr_arr_value)
           
$arr[] = $grouped_arr[$grouped_arr_key][$grouped_arr_arr_key];

    return
$arr;
}
?>

g8z at yahoo dot com (10-Jul-2006 04:58)

<?php
/**
This sort function allows you to sort an associative array while "sticking" some fields.

$sticky_fields = an array of fields that should not be re-sorted. This is a method of achieving sub-sorts within contiguous groups of records that have common data in some fields.

Courtesy of the $5 Script Archive: http://www.tufat.com
**/

define( 'ASC_AZ', 1000 );
define( 'DESC_AZ', 1001 );
define( 'ASC_NUM', 1002 );
define( 'DESC_NUM', 1003 );

function
stickysort( $arr, $field, $sort_type, $sticky_fields = array() ) {
   
$i = 0;
    foreach (
$arr as $value) {
       
$is_contiguous = true;
        if(!empty(
$grouped_arr)) {
           
$last_value = end($grouped_arr[$i]);

            if(!(
$sticky_fields == array())) {
                foreach (
$sticky_fields as $sticky_field) {
                    if (
$value[$sticky_field] <> $last_value[$sticky_field]) {
                       
$is_contiguous = false;
                        break;
                    }
                }
            }
        }
        if (
$is_contiguous)
           
$grouped_arr[$i][] = $value;
        else
           
$grouped_arr[++$i][] = $value;
    }
   
$code = '';
    switch(
$sort_type) {
        case
ASC_AZ:
           
$code .= 'return strcasecmp($a["'.$field.'"], $b["'.$field.'"]);';
            break;
        case
DESC_AZ:
           
$code .= 'return (-1*strcasecmp($a["'.$field.'"], $b["'.$field.'"]));';
            break;
        case
ASC_NUM:
           
$code .= 'return ($a["'.$field.'"] - $b["'.$field.'"]);';
            break;
        case
DESC_NUM:
           
$code .= 'return ($b["'.$field.'"] - $a["'.$field.'"]);';
            break;
    }

   
$compare = create_function('$a, $b', $code);

    foreach(
$grouped_arr as $grouped_arr_key=>$grouped_arr_value)
       
usort ( $grouped_arr[$grouped_arr_key], $compare );

   
$arr = array();
    foreach(
$grouped_arr as $grouped_arr_key=>$grouped_arr_value)
        foreach(
$grouped_arr[$grouped_arr_key] as $grouped_arr_arr_key=>$grouped_arr_arr_value)
           
$arr[] = $grouped_arr[$grouped_arr_key][$grouped_arr_arr_key];

    return
$arr;
}
?>

g8z at yahoo dot com (10-Jul-2006 04:57)

<?php
/**
This sort function allows you to sort an associative array while "sticking" some fields.

$sticky_fields = an array of fields that should not be re-sorted. This is a method of achieving sub-sorts within contiguous groups of records that have common data in some fields.

Courtesy of the $5 Script Archive: http://www.tufat.com
**/

define( 'ASC_AZ', 1000 );
define( 'DESC_AZ', 1001 );
define( 'ASC_NUM', 1002 );
define( 'DESC_NUM', 1003 );

function
stickysort( $arr, $field, $sort_type, $sticky_fields = array() ) {
   
$i = 0;
    foreach (
$arr as $value) {
       
$is_contiguous = true;
        if(!empty(
$grouped_arr)) {
           
$last_value = end($grouped_arr[$i]);

            if(!(
$sticky_fields == array())) {
                foreach (
$sticky_fields as $sticky_field) {
                    if (
$value[$sticky_field] <> $last_value[$sticky_field]) {
                       
$is_contiguous = false;
                        break;
                    }
                }
            }
        }
        if (
$is_contiguous)
           
$grouped_arr[$i][] = $value;
        else
           
$grouped_arr[++$i][] = $value;
    }
   
$code = '';
    switch(
$sort_type) {
        case
ASC_AZ:
           
$code .= 'return strcasecmp($a["'.$field.'"], $b["'.$field.'"]);';
            break;
        case
DESC_AZ:
           
$code .= 'return (-1*strcasecmp($a["'.$field.'"], $b["'.$field.'"]));';
            break;
        case
ASC_NUM:
           
$code .= 'return ($a["'.$field.'"] - $b["'.$field.'"]);';
            break;
        case
DESC_NUM:
           
$code .= 'return ($b["'.$field.'"] - $a["'.$field.'"]);';
            break;
    }

   
$compare = create_function('$a, $b', $code);

    foreach(
$grouped_arr as $grouped_arr_key=>$grouped_arr_value)
       
usort ( $grouped_arr[$grouped_arr_key], $compare );

   
$arr = array();
    foreach(
$grouped_arr as $grouped_arr_key=>$grouped_arr_value)
        foreach(
$grouped_arr[$grouped_arr_key] as $grouped_arr_arr_key=>$grouped_arr_arr_value)
           
$arr[] = $grouped_arr[$grouped_arr_key][$grouped_arr_arr_key];

    return
$arr;
}
?>

Emiliyan at ServicesBG dot Com (29-Mar-2006 03:41)

#This is a function that will sort an array...
function sort_by($array,  $keyname = null, $sortby) {
   $myarray = $inarray = array();   
   # First store the keyvalues in a seperate array
    foreach ($array as $i => $befree) {
        $myarray[$i] = $array[$i][$keyname];
    }
   # Sort the new array by
    switch ($sortby) {
    case 'asc':
    # Sort an array and maintain index association...
    asort($myarray);
    break;
    case 'arsort':
    # Sort an array in reverse order and maintain index association
    arsort($myarray);
    break;
    case 'natcasesor':
    # Sort an array using a case insensitive "natural order" algorithm
    natcasesort($myarray);
    break;
    }
    # Rebuild the old array
    foreach ( $myarray as $key=> $befree) {
       $inarray[$key] = $array[$key];
    }
    return $inarray;
}
sort_by(); example...
$info = sort_by($myarray, 'name', $use = 'asc');   
print_r($info);

ludvig dot ericson at gmail dot com (25-Feb-2006 05:48)

A tip for those who like "raul at jimi dot com dot mx" need to preserve keys after changing stuff in the middle of an array:
array_values.

Example:
<?php
$array
= array(1, 2, 5, 9, 3);
unset(
$array[3]); // Remove index 3, which is 9.
$array = array_values($array);
?>

Hint: array_values can be fine for removing keys and reindex them by number instead, too (applies to functions like posix_pwgetuid which returns an associative array, unlike C and others, call array_values on it, and it'll be the same format IIRC.)

jesper at snt dot utwente dot nl (24-Feb-2006 09:26)

If you sort an array of objects, the first variable in the object will be used for sorting:

<?php
class foo
{
  var
$value; //First variable: Used for sorting
 
var $id;

  function
foo($i, $v)
  {
    
$this->id = $i;
    
$this->value = $v;
  }

}

for (
$i = 0; $i < 10; $i++)
{
 
$bar[] = new foo($i,rand(1,10));
}

// This will sort on value
sort($bar);
print_r($bar);
?>

Compare the piece of code above with the following:

<?php
class foo
{
  var
$id; //First variable: Used for sorting
 
var $value;

  function
foo($i, $v)
  {
    
$this->id = $i;
    
$this->value = $v;
  }

}

for (
$i = 0; $i = 10; $i++)
{
 
$bar[] = new foo($i,rand(1,10));
}

// This will sort on id
sort($bar);
print_r($bar);
?>

As you can see the location of declaration of the variables matter!
If you want to sort on both or on a combination of variables, use ksort()

jerome a-t+ yamafoto d*o*t com (22-Feb-2006 05:39)

when sorting an array, beware of variable type from elements you put in this array

Example:

$a = 2; // $a is an integer
$b = 'item';
$arr = array($a, $b);
sort($arr);

print_r($arr);

this will output:
$arr[0] = 'item';
$arr[1] = 2;

$a = '2'; // $a is a string
$b = 'item';
$arr = array($a, $b);
sort($arr);

print_r($arr);

this will output:
$arr[0] = '2';
$arr[1] = 'item'

to avoid this problem use:

sort($arr, SORT_STRING)

nm at thenoodleman dot com (31-Jan-2006 01:18)

Faster, more effective function:

array_sort (array, ['asc'/'desc'])

Second parameter specifies whether to order ascending or descending. Default is ascending.

function array_sort($array, $type='asc'){
    $result=array();
    foreach($array as $var => $val){
        $set=false;
        foreach($result as $var2 => $val2){
            if($set==false){
                if($val>$val2 && $type=='desc' || $val<$val2 && $type=='asc'){
                    $temp=array();
                    foreach($result as $var3 => $val3){
                        if($var3==$var2) $set=true;
                        if($set){
                            $temp[$var3]=$val3;
                            unset($result[$var3]);
                        }
                    }
                    $result[$var]=$val;   
                    foreach($temp as $var3 => $val3){
                        $result[$var3]=$val3;
                    }
                }
            }
        }
        if(!$set){
            $result[$var]=$val;
        }
    }
    return $result;
}

Works for ordering by integers or strings, no need to specify which.

Example:

$array=array('a' => 50, 'b' => 25, 'c' => 75);
print_r(array_sort($array));

Returns:
Array
(
[b] => 25
[a] => 50
[c] => 75
)

james at miicro dot net (24-Jan-2006 06:26)

Further to john dot dutcher at highmark dot com's comments - padding the name could cause a problem if you get abnormally long names, it might be better to rebuild the array thus:

Array (
[0] => Array ( [sortname_01] => Dutcher [sortname_02] => F [sortname_03] => John [name] => Dutcher, John F )
[1] => Array ( [sortname_01] => Dutch [sortname_02] => A [sortname_03] => Roger [name] => Dutch, Roger A )
[2] => Array ( [sortname_01] => Dut [sortname_02] => H [sortname_03] => Maurice [name] => Dut, Maurice H )
[3] => Array ( [sortname_01] => Dut [sortname_02] => S [sortname_03] => Mildred [name] => Dut, Mildred S )
)

which should give:

Array (
[0] => Array ( [sortname_01] => Dut [sortname_02] => H [sortname_03] => Maurice [name] => Dut, Maurice H )
[1] => Array ( [sortname_01] => Dut [sortname_02] => S [sortname_03] => Mildred [name] => Dut, Mildred S )
[2] => Array ( [sortname_01] => Dutch [sortname_02] => A [sortname_03] => Roger [name] => Dutch, Roger A )
[3] => Array ( [sortname_01] => Dutcher [sortname_02] => F [sortname_03] => John [name] => Dutcher, John F )
)

john dot dutcher at highmark dot com (11-Jan-2006 12:58)

Regarding the array sorting of names by 'whatever' ....

That post addresses a nearly identical issue with sorting that I also have.

I just wanted to inquire though.........wouldn't the building of the 'sortname'  value require that the last name and first name be padded to their full size as they are placed into the
'sortname' field in order to get proper sorting/alignment ?

Otherwise would one have .......

    dutcherjohnf                   (Dutcher, John F)
    dutchrogera                   (Dutch, Roger A)
    dutmauriceh                   (Dut, Maurice H)

Instead of:

    dut           maurice         h    
    dutch         roger          a
    dutcher      john            f

John D.

raul at jimi dot com dot mx (02-Dec-2005 05:50)

I had an array like this:
$arr=array (1,4,3,6,5);

which returns this:
$arr[0]=1
$arr[1]=4
$arr[2]=3
$arr[3]=6
$arr[4]=5

But lets say i remove [2] which is number 3, i get:

$arr[0]=1
$arr[1]=4
$arr[3]=6
$arr[4]=5

And i want to reindex without doing a sort because i dont want to lose the order of the numbers (like a pop in a stack but in the middle of the list), i do this:

$arr=array_chunk($arr,count($arr));
$arr=$arr[0];

the result is:

$arr[0]=1
$arr[1]=4
$arr[2]=6
$arr[3]=5

This can be applied mostly for tree sorting, when you only have the id and the parent values of the node, and you want to have N levels.

phillip dot metzger at gmail dot com (09-Nov-2005 05:36)

For a case insensitive sort use this array_multisort().

<?php
$array_var
= Array("Cheery", "zap", "Banana", "apple", "Zing");

array_multisort((strtolower($array_var)), SORT_ASC, SORT_STRING, $array_var);
?>

Result order:
apple
Banana
Cheery
zap
Zing

james at miicro dot net (19-Jul-2005 10:49)

It's useful to know that if you're using this function on a multidimensional array, php will sort the first key, then the second and so on. This is similar to being able to use SQL to order by field1, field2 etc.

So:

Array (
[0] => Array ( [category] => work [name] => Smith )
[1] => Array ( [category] => play [name] => Johnson )
[2] => Array ( [category] => work [name] => Berger )
)

will become:

Array (
[0] => Array ( [category] => play [name] => Johnson )
[1] => Array ( [category] => work [name] => Berger )
[2] => Array ( [category] => work [name] => Smith )
)

Hope it helps someone.

whatever at toposphere dot com (02-Jul-2005 09:12)

The usort solution below still has problems when sorting strings of different lengths, just like the other flavors of sort that I've tried.

Here's a solution that I came up with -- it's kinda ugly, and it might not be practical for large arrays, but it's works great for me.

I'm getting some people's names out of mySQL and placing them in an array like this: "$lastname, $firstname $middlename". Because some people don't have middle names, "sort" screws up the alphabetization. So what I've done is this:

$index = 0;
while ($rows = mysql_fetch_array($sqlResult)) {
    extract($rows);
    $my_array[$index]['sortname'] = strtolower(preg_replace("/[^a-zA-Z]/", "", "$lastname$firstname$middlename"));
    $my_array[$index]['name'] = trim("$lastname, $firstname $middlename");
    $index++;
}
sort($my_array); // now in perfect alpha order

My "hack" is in the fourth line -- I take the entire name, last name first, and use preg_replace() to take out all non-letter characters, and then used strtolower() to make it all lowercase to ensure all letters would be treated equally by PHP. This goes into the ['sortname'] key within the array.

(The ['sortname'] value has to come before ['name'], or else the array will be sorted by ['name'] instead.)

This gives me:

Array
(
   [0] => Array ( [sortname] => shmojoe [name] => Shmo, Joe )
   [1] => Array ( [sortname] => shmojoem [name] => Shmo, Joe M )
)
... and so on

So the array gets sorted by ['sortname'], which never needs to be displayed, and the associated ['name'] can be displayed in perfect alphabetical order, whether there is one name, two names or three. And because ['sortname'] is letters only, it works great for hyphenated last names or ones with apostrophes, like Smith-Jones or O'Donnell.

I feel that the dual preg_replace() and strtolower() may not be the best theoretical solution, and I don't know how it would run on a really large array, but as I said, it's a great solution for my little site.

dwatson at planandgrow dot com (19-Mar-2005 01:55)

Here is a recursive use of sort for multi-dim arrays:

<?php

/*Mulsort function recursively sorts a  multi-dimensional, numeric array in place,
regardless of how many dimensions it has.  The array can be ragged -- not a matrix. 
*/

function mulsort(&$a)
{
   
sort($a);
   
$c = count($a);
    for(
$i = 0; $i < $c; $i++)
        if (
is_array($a[$i]))
           
mulsort($a[$i]);
}

//The following array is just used to demo the mulsort function.
$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>";

?>

timc at hlyw dot com (18-Feb-2005 12: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)
{
 
// $array  - the array to be sorted
  // $column - index (column) on which to sort
  //          can be a string if using an associative array
  // $order  - SORT_ASC (default) for ascending or SORT_DESC for descending
  // $first  - start index (row) for partial array sort
  // $last  - stop  index (row) for partial array sort
  // $keys  - array of key values for hash array sort
 
 
$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);
  }
}
?>

anthony at ectrolinux dot com (09-Sep-2004 12: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 09: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 08: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...

matias at arenasoftware dot com (24-Mar-2003 01: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 08:23)

Ik you want to sort case insensitive, use the natcasesort()

shailu_agrawal at yahoo dot no_spam dot com (13-Nov-2002 02: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 10: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                                                                                         
//tab-delimited ASCII file to sort - no more than one linefeed at end                         
$infile="members.txt";
//first column on left to display - count from 0
$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>";
?>

(14-Mar-2002 10: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');

--ed: In PHP 4.4 and PHP 5.0 you can do:
setlocale("LC_ALL", "de_DE");
sort($arraytobesorted, SORT_LOCALE_STRNG);

RunMaster at gmx dot de (29-Aug-2001 06: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... ;-)

phpdotnetNO_SPAM at electronic-strategy dot com (05-Jul-2001 05: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 05: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);'));

peek at mailandnews dot com (07-Apr-2001 12: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);'));

ultrafunkula at mad dot scientist dot com (31-Mar-2000 06: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 06:58)

Note that using sort() it seems to sort by ASCII code, because "AC" is before "Ab" in the result array