Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Array Functions : asort

asort

Sort an array and maintain index association (PHP 4, PHP 5)
bool asort ( array &array [, int sort_flags] )

Example 297. asort() example

<?php
$fruits
= array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
asort($fruits);
foreach (
$fruits as $key => $val) {
   echo
"$key = $val\n";
}
?>

The above example will output:

c = apple
b = banana
d = lemon
a = orange

Related Examples ( Source code ) » asort



Code Examples / Notes » asort

bwuhlman

Well, actually, asort has *two* annoying features.
It works perfectly well sorting hashes (or associative arrays, as you might have it), but doggedly refuses to sort regular arrays maintaining index assocation. Kind've makes sense, but the docs don't explicitly say you can't do it.
Urgggh.


smileaf

This revised version removes the ".$key" from the hash as I wasn't sure why it was there and caused sorting problems for me.
And allows the use of the array flags in both ksort and krsort.
<?
function record_sort($records, $field, $reverse=false, $flags=0)
{
$hash = array();

foreach($records as $key => $record)
{
$hash[$record[$field]] = $record;
}

($reverse)? krsort($hash, $flags) : ksort($hash, $flags);

$records = array();

foreach($hash as $record)
{
$records []= $record;
}

return $records;
}
?>


richard

This is a function to sort an indexed 2D array by a specified sub array key, either ascending or descending.
It is usefull for sorting query results from a database by a particular field after the query has been returned
This function can be quite greedy. It recreates the array as a hash to use ksort() then back again
By default it will sort ascending but if you specify $reverse as true it will return the records sorted descending
<?php
function record_sort($records, $field, $reverse=false)
{
$hash = array();

foreach($records as $record)
{
$hash[$record[$field]] = $record;
}

($reverse)? krsort($hash) : ksort($hash);

$records = array();

foreach($hash as $record)
{
$records []= $record;
}

return $records;
}
// Example below
$airports = array
(
array( "code" => "LHR", "name" => "Heathrow" ),
array( "code" => "LGW", "name" => "Gatwick" ),
);
printf("Before: <pre>%s</pre>", print_r($airports, true));
$airports = record_sort($airports, "name");
printf("After: <pre>%s</pre>", print_r($airports, true));
?>
Example Outputs:
Before: Array
(
[0] => Array ( [code] => LHR, [name] => Heathrow )
[1] => Array ( [code] => LGW, [name] => Gatwick )
)
After: Array
(
[0] => Array ( [code] => LGW, [name] => Gatwick )
[1] => Array ( [code] => LHR, [name] => Heathrow )
)


otterley.at.dynamine.net

This function is the equivalent of sort values %hash in Perl.

greenie2600

The function offered by richard at happymango dot me dot uk does not handle numeric indices properly. smileaf's suggested fix did not work for me. Use with caution.

freeman

The asortbyindex($sortarray, $index) looks like sort not asort. The key of the $sortarray was changed.

spectre

that works nicely, tho it breaks the result-array up if one or more of arrays indexes are deleted before sorting. this one should fix it up:
change:
for ($i = 0; $i < sizeof($array); $i++) {
to:
foreach ($array as $i => $k) {


01-aug-2002 02:48

Sorry, my last post had a typo:
// unnecessary backslashes break create_function, oops.
 if ( is_string($var) ) $var = "\'$var\'";
//it should be:
 if ( is_string($var) ) $var = "'$var'";
-- FIXED and TESTED -- :)
Similar to above but for an array of arrays instead of an array of objects.
<?php
function aasort($x,$var,$cmp='strcasecmp'){
 if ( is_string($var) ) $var = "'$var'";
 uasort($x,
   create_function('$a,$b',
     'return '.$cmp.'( $a['.$var.'],$b['.$var.']);')
 );
 return $x;
}
?>


phzzzt .a.t. acm .d.o.t. org

Similar to above but for an array of arrays instead of an array of objects.
<?php
function aasort($x,$var,$cmp='strcasecmp'){
 if ( is_string($var) ) $var = "\'$var\'";
 uasort($x,
   create_function('$a,$b',
     'return '.$cmp.'( $a['.$var.'],$b['.$var.']);')
 );
 return $x;
}
?>


smileaf

Ok I was mistaken, after re-reading the previous post the ".$key" is important. What caused the sorting issue for me wasn't that at all. But rather something else.
doing an: asort($records, $flags); before returning fixes the sorting problems.
The sorting problem I was refearing to causes a character based sorting done on numeric data.
so instead of:
1
2
3
...
10
12
20
It was returned back as
1
10
12
2
20
3
...
basically what I was trying to fix in the first place.


mbevan

Nevermind... use my last note as a quick tip: if you wish to keep the keys, use asort() and arsort() in place of sort() and rsort().

acecream

my version of sorting multi dimensional array
<?php
function array_sort($array, $key)
{
  for ($i = 0; $i < sizeof($array); $i++) {
       $sort_values[$i] = $array[$i][$key];
  }
  asort ($sort_values);
  reset ($sort_values);
  while (list ($arr_key, $arr_val) = each ($sort_values)) {
         $sorted_arr[] = $array[$arr_key];
  }
  return $sorted_arr;
}
?>


martin dot edelius

In the 'asortbyindex' function above there's a $ sign missing from a variable in one of the for loops:
for ($iteration = 0; $iteration < $lastiteration; iteration++)
should be:
for ($iteration = 0; $iteration < $lastiteration; $iteration++)


csaba

If you have a pair of arrays which have a one to one association (examples: spouses, first to last name, SSN to name), when you sort one, you might wish to sort the other in the same way to maintain the correlation.  This example illustrates a way:
<?php
$aMen = array('Fred', 'Bob', 'Tim', 'John', 'Bill');
$aPartner = array('Sue', 'Mary', 'Ann', 'Cathy', 'Nancy');
asort($aMen);                   // aMen now sorted; numeric keys out of order
$aWomen = array_keys($aMen);    // create a new array for result
foreach ($aWomen as $idx => &$name) $name=$aPartner[$name];
                               // aWomen now has the sorted partners
$aMen = array_merge($aMen);     // put the numeric keys in order
?>
Csaba Gabor


a dot brandon

I use this for quasi-SQL orderby. Loosely based on smileaf. Any good for you nerds?
<?
function named_records_sort($named_recs, $order_by, $rev=false, $flags=0)
{// Create 1-dimensional named array with just
// sortfield (in stead of record) values
   $named_hash = array();
    foreach($named_recs as $key=>$fields)
            $named_hash["$key"] = $fields[$order_by];

// Order 1-dimensional array,
// maintaining key-value relations  
   if($reverse) arsort($named_hash,$flags=0) ;
   else asort($named_hash, $flags=0);
 
// Create copy of named records array
// in order of sortarray  
   $sorted_records = array();
   foreach($named_hash as $key=>$val)
          $sorted_records["$key"]= $named_recs[$key];
 
return $sorted_records;} // named_recs_sort()
function show_sorted_records($named_recs, $order_by, $rev=false, $flags=0)
{$sorted_records=named_records_sort($named_recs, $order_by, $rev, $flags);
foreach($sorted_records as $name=>$fields)
 {echo "<b>$name</b>   ";
  foreach($fields as $field=>$val)
         echo "$field = $val "; echo "
";}
} // show_sorted_records()
$girl_friends=array();
$girl_friends["Anna"]=
array("born"=>'1989-08-22',"cupsize"=>'B-',"IQ"=>105, "daddy"=>'rich');
$girl_friends["Zoe"]
=array("born"=>'1978-03-11',"cupsize"=>'C#',"IQ"=>130, "daddy"=>'poor');
$girl_friends["Lilly"]
=array("born"=>'1985-06-16',"cupsize"=>'DD',"IQ"=>90, "daddy"=>'nasty');
$order_by="cupsize"; echo "And the winners are:
";
show_sorted_records($girl_friends, $order_by, true);
?>


odeen

hi
the 2d arry sort works good for me,
but you should use
strtolower()
for the right alphabetical order, like this:for ($index = 0; $index < strlen ($s1); $index++) {
/**
** $s1 comes after $s2
**/
if (strtolower($s1[$index]) > strtolower($s2[$index])) return ($order);
/**
** $s1 comes before $s2
**/
if (strtolower($s1[$index]) < strtolower($s2[$index])) return (1 - $order);
}
have fun olli


salchicha

Here's one I whipped up to allow you to sort an array of a specific class by a member or function:
<?php
// Sort a class by one of its members (even lowercase!!!)
function casort($arr, $var) {
  $tarr = array();
  $rarr = array();
  for($i = 0; $i < count($arr); $i++) {
     $element = $arr[$i];
     $tarr[] = strtolower($element->{$var});
  }
  reset($tarr);
  asort($tarr);
  $karr = array_keys($tarr);
  for($i = 0; $i < count($tarr); $i++) {
     $rarr[] = $arr[intval($karr[$i])];
  }
  return $rarr;
}
?>
It works very well. For example, I have a Room class with members title, isActive(), date, etc. I can sort an array by casort($rooms, "title") or casort($rooms, "isActive()") and it'll work.


rcwang

Here's my version of sorting multi-dimensional array by 2nd index.
Feel free to change the code to suit your needs.
<?php
function aSortBySecondIndex($multiArray, $secondIndex) {
while (list($firstIndex, ) = each($multiArray))
$indexMap[$firstIndex] = $multiArray[$firstIndex][$secondIndex];
asort($indexMap);
while (list($firstIndex, ) = each($indexMap))
if (is_numeric($firstIndex))
$sortedArray[] = $multiArray[$firstIndex];
else $sortedArray[$firstIndex] = $multiArray[$firstIndex];
return $sortedArray;
}
?>


sweetland

Here's a little routine I whipped up to sort multi-dimensional arrays:
<?php
/**
** comesafter ($s1, $s2)
**
** Returns 1 if $s1 comes after $s2 alphabetically, 0 if not.
**/
function comesafter ($s1, $s2) {
       /**
        ** We don't want to overstep the bounds of one of the strings and segfault,
        ** so let's see which one is shorter.
        **/
       $order = 1;
       if (strlen ($s1) > strlen ($s2)) {
               $temp = $s1;
               $s1 = $s2;
               $s2 = $temp;
               $order = 0;
       }
       for ($index = 0; $index < strlen ($s1); $index++) {
               /**
                ** $s1 comes after $s2
                **/
               if ($s1[$index] > $s2[$index]) return ($order);
               /**
                ** $s1 comes before $s2
                **/
               if ($s1[$index] < $s2[$index]) return (1 - $order);
       }

       /**
        ** Special case in which $s1 is a substring of $s2
        **/
       return ($order);
}
/**
** asortbyindex ($sortarray, $index)
**
** Sort a multi-dimensional array by a second-degree index. For instance, the 0th index
** of the Ith member of both the group and user arrays is a string identifier. In the
** case of a user array this is the username; with the group array it is the group name.
** asortby
**/
function asortbyindex ($sortarray, $index) {
       $lastindex = count ($sortarray) - 1;
       for ($subindex = 0; $subindex < $lastindex; $subindex++) {
               $lastiteration = $lastindex - $subindex;
               for ($iteration = 0; $iteration < $lastiteration;    iteration++) {
                       $nextchar = 0;
                       if (comesafter ($sortarray[$iteration][$index], $sortarray[$iteration + 1][$index])) {
                               $temp = $sortarray[$iteration];
                               $sortarray[$iteration] = $sortarray[$iteration + 1];
                               $sortarray[$iteration + 1] = $temp;
                       }
               }
       }
       return ($sortarray);
}
?>
It's a bit long with all the comments, but I hope it helps.


komashooter

here another version from acecream multisorting for arrays :)

<?php
function array_sort_multi2($array, $key,$key2)
{
 for ($i = 0; $i < sizeof($array); $i++) {
      if(! empty($array[$i][$key][$key2])){
      $sort_values[$i] = $array[$i][$key][$key2];
  }else{
  $sort_values[$i] = $array[$i];
  }
 }
 asort ($sort_values);
 reset ($sort_values);
 while (list ($arr_keys, $arr_values) = each ($sort_values)) {
        $sorted_arr[] = $array[$arr_keys];
 }
 return $sorted_arr;
}
?>


przemekkus

Function written by a dot brandon at chello dot nl has an error  - wrong variable name. It should be:
if($rev) arsort($named_hash,$flags=0) ;
instead of
if($reverse) arsort($named_hash,$flags=0) ;


nilesh dot gamit

function to sort 2d array: recordSort(); It is really helpful as most PHP sort functions provides facility for sorting 1d array & multi dimensional array sorting is not handy. Normally this function will help u.. if u r displaying some records n u want sorting by clicking on some column. basically same is achieved by direct SQL changes like ORDER BY ASC/DESC. But in case, if your records are not actual records, this function will help. i.e. some table has following fields in DB.
name, email, telephone and are_you_married; are_you_married is either 0 / 1. now u r displaying N for 1 and Y for 0; and you want sorting on are_you_married on display. then ORDER BY ASC/DESC. will not work. So, try this…
<?php
   function recordSort($records, $field, $reverse, $defaultSortField = 0)
   {
           $uniqueSortId = 0;
           $hash = array(); $sortedRecords = array(); $tempArr = array(); $indexedArray = array(); $recordArray = array();
           foreach($records as $record) {
               $uniqueSortId++;
               $recordStr = implode("|", $record)."|".$uniqueSortId;
               $recordArray[] = explode("|", $recordStr);
           }
           $primarySortIndex = count($record);
           $records = $recordArray;
            foreach($records as $record) {
$hash[$record[$primarySortIndex]] = $record[$field];
}
           uasort($hash, "strnatcasecmp");
           if($reverse)
           $hash = array_reverse($hash, true);
           $valueCount = array_count_values($hash);
           foreach($hash as $primaryKey => $value) {
$indexedArray[] = $primaryKey;
           }          
           $i = 0;
           foreach($hash as $primaryKey => $value) {
               $i++;
               if($valueCount[$value] > 1) {
                   foreach($records as $record)  {
                       if($primaryKey == $record[$primarySortIndex]) {
                           $tempArr[$record[$defaultSortField]."__".$i] = $record;
                           break;
                       }
                   }
                   $index = array_search($primaryKey, $indexedArray);
                   if( ($i == count($records)) || ($value != $hash[$indexedArray[$index+1]]) )  {
                       uksort($tempArr, "strnatcasecmp");
                       if($reverse)
                       $tempArr = array_reverse($tempArr);
                       foreach($tempArr as $newRecs) {
                           $sortedRecords [] = $newRecs;
                       }
                       $tempArr = array();
                   }
               }
               else {
                   foreach($records as $record)  {
                      if($primaryKey == $record[$primarySortIndex])  {
                               $sortedRecords[] = $record;
                               break;
                       }
                   }
               }
           }
           return $sortedRecords;
   }
   $array[0][0] = 'nilesh';   // sort_index = 0
   $array[0][1] = 'yogesh'; // sort_index = 1
   $array[0][2] = 'aakash'; // sort_index = 2
   $array[0][3] = '100';      // sort_index = 3
   $array[0][4] = 'nilesh';   // sort_index = 4
   $array[0][5] = 'Nil100';  // sort_index = 5
   $array[0][6] = 'Y';         // sort_index = 6
   $array[1][0] = 'Nil100';
   $array[1][1] = '1001';
   $array[1][2] = 'nilesh';
   $array[1][3] = 'nilesh';
   $array[1][4] = 'nilesh';
   $array[1][5] = 'yogesh';
   $array[1][6] = 'Nil100';
   $array[2][0] = 'Nil100';
   $array[2][1] = 'Y';
   $array[2][2] = '100';
   $array[2][3] = '10nilesh';
   $array[2][4] = 'aakash';
   $array[2][5] = '_aakash';
   $array[2][6] = 'aakash_';
   echo "array before sorting..."
   print_r($array);
   /* $sortedList = recordSort(2d_array, sort_index, reverse, second_level_sort_index_if_duplicates_found_default_is_0 = '0'); */
   $sortedList = recordSort($array, 4, 0, 5);
   echo "array after sorting..."
   print_r($sortedList);
?>


markus

for sorting CASEINSENSITIVE try
natcasesort()
there's little difference to sort,
but maybe that doesn't matter for you.


gunnar

for ($i=0;$i<5;$i++)
  $values[] = $i;
asort($values);  
works, but
for ($i=0;$i<5;$i++)
  $values[$i] =$i;
asort($values);
doesn't!


jacko

asort has one anoying feature, it ignores any default or implicit order in the data.  i.e. if two elements of an array contain "banana" then it is not garanteed that the first will still be the first after the sort.
This makes the Burrows-Wheeler block sort a bit of a pain to impliment, with a trailing string having to be appended to all strings before sorting, and removed after sorting. To maintain the so called "banana" order.


rojaro

Advanced sort array by second index function, which produces ascending (default) or descending output and uses optionally natural case insensitive sorting (which can be optionally case sensitive as well).
Only the first two arguments are required.
<?php
function sabsi ($array, $index, $order='asc', $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) ($order=='asc')? asort($temp) : arsort($temp);
   else {
     ($case_sensitive)? natsort($temp) : natcasesort($temp);
     if($order!='asc') $temp=array_reverse($temp,TRUE);
   }
   foreach(array_keys($temp) as $key) (is_numeric($key))? $sorted[]=$array[$key] : $sorted[$key]=$array[$key];
   return $sorted;
 }
 return $array;
}
?>


php

acecream's function works fine, especially with the spectre extension.
nevertheless sometimes the index values have to be kept. To achieve this, just replace:
$sorted_arr[] = $array[$arr_key];  
with:
$sorted_arr[$arr_key] = $array[$arr_key];


Change Language


Follow Navioo On Twitter
array_change_key_case
array_chunk
array_combine
array_count_values
array_diff_assoc
array_diff_key
array_diff_uassoc
array_diff_ukey
array_diff
array_fill_keys
array_fill
array_filter
array_flip
array_intersect_assoc
array_intersect_key
array_intersect_uassoc
array_intersect_ukey
array_intersect
array_key_exists
array_keys
array_map
array_merge_recursive
array_merge
array_multisort
array_pad
array_pop
array_product
array_push
array_rand
array_reduce
array_reverse
array_search
array_shift
array_slice
array_splice
array_sum
array_udiff_assoc
array_udiff_uassoc
array_udiff
array_uintersect_assoc
array_uintersect_uassoc
array_uintersect
array_unique
array_unshift
array_values
array_walk_recursive
array_walk
array
arsort
asort
compact
count
current
each
end
extract
in_array
key
krsort
ksort
list
natcasesort
natsort
next
pos
prev
range
reset
rsort
shuffle
sizeof
sort
uasort
uksort
usort
eXTReMe Tracker