Reputation:
What's the best way in PHP to sort an array of arrays based on array length?
e.g.
$parent[0] = array(0, 0, 0);
$parent[2] = array("foo", "bar", "b", "a", "z");
$parent[1] = array(4, 2);
$sorted = sort_by_length($parent)
$sorted[0] = array(4, 2);
$sorted[1] = array(0, 0, 0);
$sorted[2] = array("foo", "bar", "b", "a", "z");
Upvotes: 2
Views: 1617
Reputation: 47903
sort()
compares by size before quality.
Because all of your rows have the same flat structure, sort()
will sort ascending by row size, sort ascending by first elements, then the next elements, etc.
Code: (Demo)
$parent[0] = array(0, 0, 0);
$parent[2] = array("foo", "bar", "b", "a", "z");
$parent[1] = array(4, 2);
$parent[5] = array(11, 2);
$parent[3] = array(1, 21);
$parent[4] = array(11, 1);
sort($parent);
var_export($parent);
Output:
array (
0 =>
array (
0 => 1,
1 => 21,
),
1 =>
array (
0 => 4,
1 => 2,
),
2 =>
array (
0 => 11,
1 => 1,
),
3 =>
array (
0 => 11,
1 => 2,
),
4 =>
array (
0 => 0,
1 => 0,
2 => 0,
),
5 =>
array (
0 => 'foo',
1 => 'bar',
2 => 'b',
3 => 'a',
4 => 'z',
),
)
This performs identically to this use of array_multisort()
with iterated calls of count
: (Demo)
array_multisort(array_map('count', $parent), $parent);
var_export($parent);
Using usort()
is different if only sorting on the counts because in modern PHP it will leave tied comparisons in their original position : (Demo)
usort($parent, fn($a, $b) => count($a) <=> count($b));
var_export($parent);
Upvotes: 0
Reputation: 1470
Try the usort
function:
function sortByLength( $arr1, $arr2 )
{
$c1 = count($arr1);
$c2 = count($arr2);
return $c1 < $c2 ? -1 : $c1 == $c2 ? 0 : 1;
}
usort($initial_array,'sortByLength');
edited to respect parameters-by-reference; it's the same answer as @david, anyway
Upvotes: 0
Reputation: 131600
I'm upvoting Peter's but here's another way, I think:
function cmp($a1, $a2) {
if (count($a1) == count($a2)) {
return 0;
}
return (count($a1) < count($a2)) ? -1 : 1;
}
usort($array, "cmp");
Upvotes: 3
Reputation: 91028
This will work:
function sort_by_length($arrays) {
$lengths = array_map('count', $arrays);
asort($lengths);
$return = array();
foreach(array_keys($lengths) as $k)
$return[$k] = $arrays[$k];
return $return;
}
Note that this function will preserve the numerical keys. If you want to reset the keys, wrap it in a call to array_values().
Upvotes: 4