Reputation: 157
I have a total of three arrays
Array 1
array1 = Array(
[0] => Array(
[name] => John
[city] => San Francisco
[state] => CA
)
[1] => Array(
[name] => Smith
[city] => Atlanta
[state] => GA
)
[2] => Array(
[name] => Peter
[city] => New York
[state] => NY
)
[3] => Array(
[name] => Mary
[city] => San Jose
[state] => CA
)
)
Array 2 (sorted on average age)
array2 = Array(
[0] => CA
[1] => NY
[2] => GA
)
Array 3 (sorted based on population)
array3 = Array(
[0] => New York
[1] => San Francisco
[2] => Atlanta
[3] => San Jose
)
How do I sort array 1 based on array 2 first and then by array 3. I want the following output:
Sorted Array 1
Array
(
[0] => Array
(
[name] => John
[city] => San Francisco
[state] => CA
)
[1] => Array
(
[name] => Mary
[city] => San Jose
[state] => CA
)
[2] => Array
(
[name] => Peter
[city] => New York
[state] => NY
)
[3] => Array
(
[name] => Smith
[city] => Atlanta
[state] => GA
)
)
I tried using array_multisort
for achieving this, but it's not working, e.g.
array_multisort($array2,$array3,$array1)
Any help is highly appreciated.
Upvotes: 1
Views: 177
Reputation: 1592
Here's one way to sort $array1
by $array2
and $array3
to produce the results you want:
<?php
$array1 = array(
array('name' => 'John', 'city' => 'San Francisco', 'state' => 'CA'),
array('name' => 'Smith', 'city' => 'Atlanta', 'state' => 'GA'),
array('name' => 'Peter', 'city' => 'New York', 'state' => 'NY'),
array('name' => 'Mary', 'city' => 'San Jose', 'state' => 'CA'),
);
$array2 = array(
'CA',
'NY',
'GA'
);
$array3 = array(
'New York',
'San Francisco',
'Atlanta',
'San Jose'
);
usort(
$array1,
function ($element1, $element2) use ($array2, $array3) {
$state_sort_order = array_flip($array2);
$element1_state_sort_order = $state_sort_order[$element1['state']];
$element2_state_sort_order = $state_sort_order[$element2['state']];
$state_sort_result = $element1_state_sort_order - $element2_state_sort_order;
if ($state_sort_result === 0) {
$city_sort_order = array_flip($array3);
$element1_city_sort_order = $city_sort_order[$element1['city']];
$element2_city_sort_order = $city_sort_order[$element2['city']];
return $element1_city_sort_order - $element2_city_sort_order;
} else {
return $state_sort_result;
}
}
);
print_r($array1);
Again, usort seemed to be the choice with the most flexibility. There might be a way to figure out how to use array_multisort, but I couldn't tell based on the data you've given.
I use a function closure, capturing $array2
and $array3
from the outer scope to do the sorting. It defines a comparison function for usort
to apply to elements of $array1
to determine sort order. In this function, $element1
and $element2
each receive the value of elements from $array1
to process for comparison, e.g 'Smith,Atlanta,GA'
, or 'Mary,San Jose,CA'
.
For each element, I extract the city and state portions of the elements. If you flip $array2
and $array3
, they become lookup tables for sort order when you index them by $city
and $state
, respectively.
The rest is just returning the difference between city sort orders if the state sort orders are equal, else just return the state sort orders.
Upvotes: 2