0

I have a two-dimensional array in PHP that contains a city, it's state, and the population. If I build it like this:

$cities = array (
                array("New York", "NY", 8008278),
                array("Los Angeles", "CA", 3694820),
                array("Chicago", "IL", 2896016),
                array("Houston", "TX", 1953631),
                array("Philadelphia", "PA", 1517550),
                array("Phoenix", "AZ", 1321045),
                array("San Diego", "CA", 1223400),
                array("Dallas", "TX", 1188580),
                array("San Antonio", "TX", 1144646),
                array("Detroit", "MI", 951270) 
            );

How can I sort by the population (3rd row) in descending order? Here is some code to output the data in a table.

echo "<table>";
            for ($row = 0; $row < 10; $row++) {
                echo "<tr>";
                for ($col = 0; $col < 3; $col++) {
                  echo "<td>".$cities[$row][$col]."</td>";
                }
                echo "</tr>";
            }
echo "</table>";
Pecker
  • 133
  • 1
  • 9
  • I would use [uasort](https://www.php.net/manual/en/function.uasort.php) and your `cmp` looks like: https://stackoverflow.com/questions/21898455/sorting-multidimensional-arrays-with-uasort – hppycoder Apr 09 '21 at 19:29

4 Answers4

3

Simple one liner to sort the array without needing to use a custom callback:

array_multisort($cities, array_column($cities, 2), SORT_DESC)
apokryfos
  • 38,771
  • 9
  • 70
  • 114
1

If you are using PHP7+, you can achieve it with something like this:

usort($cities, function($a, $b) {
    return $a[2] <=> $b[2];
});

If you are using lower version, you can change spaceship operator (<=>) to

$a[2] - $b[2]
harmoxyne
  • 71
  • 5
0

I would use a loop to pull out the integers -- Then sort them using sort()

After that I would loop through the integers array() -- And nested loop through and check for equality .. If equal .. Build up the new array ..

<?php

$cities = array (
    array("New York", "NY", 8008278),
    array("Los Angeles", "CA", 3694820),
    array("Chicago", "IL", 2896016),
    array("Houston", "TX", 1953631),
    array("Philadelphia", "PA", 1517550),
    array("Phoenix", "AZ", 1321045),
    array("San Diego", "CA", 1223400),
    array("Dallas", "TX", 1188580),
    array("San Antonio", "TX", 1144646),
    array("Detroit", "MI", 951270)
);


$city_integers = array();
foreach ($cities as $city){
    $integer = $city[2];
    array_push($city_integers, $integer);


}

sort($city_integers);

print_r ($city_integers);

$final_array = array();
foreach ($city_integers as $key =>$item){

    foreach($cities as  $city){
        if ($city[2] == $item){
            $final_array[$key] = $city;
        }
    }

}

print_r ($final_array);

OUTPUT

Array
(
    [0] => Array
        (
            [0] => Detroit
            [1] => MI
            [2] => 951270
        )

    [1] => Array
        (
            [0] => San Antonio
            [1] => TX
            [2] => 1144646
        )

    [2] => Array
        (
            [0] => Dallas
            [1] => TX
            [2] => 1188580
        )

    [3] => Array
        (
            [0] => San Diego
            [1] => CA
            [2] => 1223400
        )

    [4] => Array
        (
            [0] => Phoenix
            [1] => AZ
            [2] => 1321045
        )

    [5] => Array
        (
            [0] => Philadelphia
            [1] => PA
            [2] => 1517550
        )

    [6] => Array
        (
            [0] => Houston
            [1] => TX
            [2] => 1953631
        )

    [7] => Array
        (
            [0] => Chicago
            [1] => IL
            [2] => 2896016
        )

    [8] => Array
        (
            [0] => Los Angeles
            [1] => CA
            [2] => 3694820
        )

    [9] => Array
        (
            [0] => New York
            [1] => NY
            [2] => 8008278
        )

)
Zak
  • 6,976
  • 2
  • 26
  • 48
  • What would happen if instead of 10 cities there are 10,000? Would using multiple arrays and `foreach` statements be efficient? – hppycoder Apr 09 '21 at 19:40
  • Auto generate and test it :) I'd be willing to bet the overhead isn't noticeable .. As a matter of fact -- I'd bet the `usort` function uses looping in the background, so it would probably be identical. – Zak Apr 09 '21 at 19:42
  • It's conceptual there but I think another answer here (harmoxyne) is the shortest using the most efficient way possible. I pulled mine out to it's own function but usort would use the [native C library](https://github.com/php/php-src/blob/5caaf40b43303887a38d738a9c2a2f4cf6dc9b1a/ext/standard/array.c#L918). – hppycoder Apr 09 '21 at 19:47
  • 4 very different answers arriving at the same end .. Just another example of TMTOWTDI – Zak Apr 09 '21 at 19:50
  • 1
    Welcome to PHP! Let's show you around. lol – hppycoder Apr 09 '21 at 19:51
  • 1
    HA! Isn't that the truth! – Zak Apr 09 '21 at 19:52
0

Using what was discussed in the comments it will combine usort along with a good cmp to handle the multi-dimensional array.

The \n in the code could be removed. I put those there so you can see it in action.

<?php
function cmp($a, $b) {
    if ($a[2] == $b[2]) {
        return 0;
    }
    return ($a[2] < $b[2]) ? -1 : 1;
}

$cities = array(
    array("New York", "NY", 8008278),
    array("Los Angeles", "CA", 3694820),
    array("Chicago", "IL", 2896016),
    array("Houston", "TX", 1953631),
    array("Philadelphia", "PA", 1517550),
    array("Phoenix", "AZ", 1321045),
    array("San Diego", "CA", 1223400),
    array("Dallas", "TX", 1188580),
    array("San Antonio", "TX", 1144646),
    array("Detroit", "MI", 951270)
);


usort($cities, 'cmp');

echo "<table>\n";
foreach($cities as $city) {
    echo "<tr>\n";
    echo sprintf("  <td>%s</td><td>%s</td><td>%s</td>", $city[0], $city[1], $city[2]);
    echo "</tr>\n";
}
echo "</table>\n";

Output:

<table>
<tr>
  <td>Detroit</td><td>MI</td><td>951270</td></tr>
<tr>
  <td>San Antonio</td><td>TX</td><td>1144646</td></tr>
<tr>
  <td>Dallas</td><td>TX</td><td>1188580</td></tr>
<tr>
  <td>San Diego</td><td>CA</td><td>1223400</td></tr>
<tr>
  <td>Phoenix</td><td>AZ</td><td>1321045</td></tr>
<tr>
  <td>Philadelphia</td><td>PA</td><td>1517550</td></tr>
<tr>
  <td>Houston</td><td>TX</td><td>1953631</td></tr>
<tr>
  <td>Chicago</td><td>IL</td><td>2896016</td></tr>
<tr>
  <td>Los Angeles</td><td>CA</td><td>3694820</td></tr>
<tr>
  <td>New York</td><td>NY</td><td>8008278</td></tr>
</table>
hppycoder
  • 1,016
  • 1
  • 6
  • 13