0

For eg.

I have the following array setup that has each major US city with its human population size.

$usapopstats = array(
   array('New York',8008278),
   array('Los Angeles',3694820),
   array('Chicago',2896016),
   array('Houston',1953631),
   array('Philadelphia',1517550),
   array('Phonenix',1321045),
   array('San Diego',1223400),
   array('Dallas',1188580),
   array('San Antonio',1144646),
   array('Detroit',951270)
);

I want to sort this information by the order of their population size. But when I tried using arsort function, it sorts array by the key data, rather than the value data ie sorted by city.

So my question is how do you programme the sorting by the population size for this type of multidimensional array? Any ideas?

If the array were rewritten like this

$usapopstats = array(
    'New York'=>8008278,
    'Los Angeles'=>3694820,
    'Chicago'=>2896016,
    'Houston'=>1953631,
    'Philadelphia'=>1517550,
    'Phoenix'=>1321045,
    'San Diego'=>1223400,
    'Dallas'=>1188580,
    'San Antonio'=>1144646,
    'Detroit'=>951270
 );
 asort($usapopstats);

This will sort the array by population size.

awongCM
  • 917
  • 5
  • 22
  • 46
  • 1
    possible duplicate of [Sorting multidimensional array in PHP](http://stackoverflow.com/questions/2059255/sorting-multidimensional-array-in-php) – jprofitt Feb 14 '12 at 13:03
  • maybe just manipulate your nested array to a simple key value array and `asort()` that – T I Feb 14 '12 at 13:07
  • usort() - http://www.php.net/manual/en/function.usort.php – Mark Baker Feb 14 '12 at 13:09

1 Answers1

1

You need to create a user sort function (that is the most beautiful and fastest to program solution:

$usapopstats = array(
    array('New York',8008278),
    array('Los Angeles',3694820),
    array('Chicago',2896016),
    array('Houston',1953631),
    array('Philadelphia',1517550),
    array('Phonenix',1321045),
    array('San Diego',1223400),
    array('Dallas',1188580),
    array('San Antonio',1144646),
    array('Detroit',951270)
);

function sort_helper ($a, $b) {
    if ($a[1] > $b[1]) return 1;
    if ($a[1] == $b[1]) return 0;
    return -1;
}

usort ($usapopstats, sort_helper);
var_dump($usapopstats);

This is not the fastest code, fine for a list of say up to 1000 records, but I wouldn't do it with an array with 100,000 entries. For each compare, the sort_helper function is being called, and since n log n compares are necessary, this means just as many function calls.

If you need this for a long list, encode the population in the key, and ksort:

$usapopstats = array(
    array('New York',8008278),
    array('Los Angeles',3694820),
    array('Chicago',2896016),
    array('Houston',1953631),
    array('Philadelphia',1517550),
    array('Phonenix',1321045),
    array('San Diego',1223400),
    array('Dallas',1188580),
    array('San Antonio',1144646),
    array('Detroit',951270)
);

$statshelper = array();
foreach($usapopstats as $index=>$stat){
    $statshelper[$stat[1]."_".$index] = $stat; //also add the index to the key to avoid duplicates
}

ksort($statshelper, SORT_NUMERIC); //because the keys are strings (they contain an underscore) by default it will compare lexographically. The flag enforces numerical comparison on the part that can be converted to a number (i.e. the population)
$usapopstats = array_values($statshelper);

var_dump($usapopstats);
Claude
  • 8,806
  • 4
  • 41
  • 56
  • Thanks Claude. Your solution is sound. Though it will take me a while to comprehend your ksort code algorithm part. I haven't touched the data sort alrogithms since my college days - which was like ten years ago! Hence I'm a bit to slow to pick this up. What I don't get is if array_values function supposed to return values of statshelper array as a new array for $usapopstats array, wouldn't the usapopstats array's key/value pairs be overwritten? – awongCM Feb 15 '12 at 12:58
  • You're welcome :). The $statshelper array will have all the correct data in the values, but some "junk" that was needed just for sorting in the keys. So the `$usapopstats = array_values($statshelper);` line is just to get rid of this junk. You can dump the $statshelper variable as well to see the difference. – Claude Feb 15 '12 at 13:07