2

Given the following PHP array:

Array
(
    [0] => Array
        (
            [name] => Restaurant 123
            [city] => Arlington
            [zip] => 22201
        )

    [1] => Array
        (
            [name] => Bar Foo
            [city] => Ballston
            [zip] => 22201
         )
     [2] => Array
        (
            [name] => Restaurant XYZ
            [city] => Ballston
            [zip] => 22201
         )

    [3] => Array
        (
            [name] => Restaurant 321
            [city] => Washington DC
            [zip] => 22201
         )

)

How can I produce a list sorted according to city (alphabetically), so that it would output something like:

Arlington

Restaurant 123

Ballston

Bar Foo

Restaurant XYZ

Washington DC

Restaurant 321

E.G., sorted first by city name alphabetically, and then by venue name, also alphabetically. Also note that it's not given that the restaurant name, nor the cities are alphabetically sorted in the array given.

5 Answers 5

2

Write a callback function that you can pass to usort, for example

function compare_venues($a, $b)
{
  return strcmp($a['name'], $b['name']);
}
Sign up to request clarification or add additional context in comments.

Comments

2

You can use usort, which enables you to sort an array based on a user-defined comparison function.

Comments

2

Try usort ( http://php.net/manual/en/function.usort.php ) where you can define a custom sort schema like

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

Comments

1

Looks like theres two parts to what you want - sorting and displaying.

To sort, you want to use usort with small function defining the comparison

$sortFunc = function($a,$b) {return $a['city'] != $b['city'] 
                                 ? $a['city'] > $b['city']
                                 : $a['name'] > $b['name'];};

        // = function($a,$b) {return $a['city'] > $b['city'] || ($a['city'] == $b['city'] && $a['name'] > $b['name']);};
        // = function($a,$b) {return 100*strcmp($a['city'],$b['city']) + strcmp($a['name'],$b['name']);};
usort($arr, $sortFunc);

function displayNamesGroupedByCity($arr)
{
    $lastCity = '';
    foreach($arr as $v)
    {
        if ($v['city'] != $lastCity)
        {
             $lastCity = $v['city'];
             echo "<br /><strong>$lastCity</strong><br />";
        }
        else echo ', ';
        echo $v['name'];
    }
}

displayNamesGroupedByCity($arr);

For the hell of it im going to make things generic

function displayXgroupedByY($arr, $x, $y)
{
    $sortFunc = function($a,$b) use($x,$y) 
                               {return $a[$y] != $b[$y] 
                                 ? $a[$y] > $b[$y]
                                 : $a[$x] > $b[$y];};

    user($arr, $sortFunc);

    $lastCity = '';
    foreach($arr as $v)
    {
        if ($v['city'] != $lastCity)
        {
             $lastCity = $v['city'];
             echo "<br /><strong>$lastCity</strong><br />";
        }
        else echo ', ';
        echo $v['name'];
    }
    return $arr;
}

displayXGroupedByY($arr, 'name', 'city');

5 Comments

Hi Jon, I tried your sort function but a print_r($sorted) just gives me "1" instead of a sorted list? Apart from the missing apostrophes which I guess SO removed.
yes, i fixed it. usort sorts in place, the return value is boolean
OK cool, this ALMOST works, except the items seem to be in reverse order, eg. both the cities and the venues are backwards?
hah i just noticed that myself. you switched the comparisons to less thans i guess?
I just reversed the $a, $b in the $sortFunc = function() :)
1

user defined sorting should do a work:

https://www.php.net/manual/en/function.uasort.php

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.