'Usort function to sort and group
I have this array.
Array
(
[0] => Array
(
[name] => SUNDERLAND
[pts] => 2
[gd] => -4
[group] => A
)
[1] => Array
(
[name] => NEWCASTLE
[pts] => 2
[gd] => -3
[group] => C
)
[2] => Array
(
[name] => STOKE CITY
[pts] => 2
[gd] => -2
[group] => B
)
[3] => Array
(
[name] => WATFORD
[pts] => 3
[gd] => -2
[group] => A
)
[4] => Array
(
[name] => TOTTENHAM
[pts] => 3
[gd] => -1
[group] => B
)
[5] => Array
(
[name] => CHELSEA
[pts] => 4
[gd] => -5
[group] => C
)
[6] => Array
(
[name] => NORWICH
[pts] => 4
[gd] => -3
[group] => D
)
[7] => Array
(
[name] => WEST BROM
[pts] => 4
[gd] => -4
[group] => D
)
)
I must sort and group this array elements by some criterias.
In the same group first NAME is name with greater pts parameter (DESC by pts parameter). If pts parameters the same order by gd parameter (DESC by gd parameter)
Team names with the same Group together.
Name pts gd group
WATFORD 3 -2 A
SUNDERLAND 2 -4 A
TOTTENHAM 3 -1 B
STOKE CITY 2 -2 B
CHELSEA 4 -5 C
NEWCASTLE 2 -3 C
NORWICH 4 -3 D
WEST BROM 4 -4 D
in this moment I can sort by pts and gd as follows:
<?php
function sortByOrder($a, $b){
$c = $a['pts'] - $b['pts'];
$c .= $a['gd'] - $b['gd'];
return $c;
}
usort($all_teams_nf, 'sortByOrder');
foreach($all_teams_nf as $myarr){
foreach($myarr as $key => $team){
if($key!="pts" and $key!="gd" and $key!="group"){
$all_teams[] = $team;
}
}
}
$all_teams = array_reverse($all_teams);
?>
Please help to combine by groups and then in each group order by pts and gd. (In final result I need to show group name and team names!
A
WATFORD
SUNDERLAND
B
TOTTENHAM
STOKE CITY
C
CHELSE
NEWCASTLE
D
NORWICH
WEST BROM
Solution 1:[1]
I would use array_multisort instead of usort for this. First group your rows by the group key. Then use array_multisort on each group. Finally you can use ksort if you need the groups to appear in sorted order as well.
$arraysByGroup = array();
// group by group key
foreach($array as $element) {
$arraysByGroup[$element['group']][] = $element;
}
// sort each group by name, pts, gd
foreach($arraysByGroup as &$group) {
$name = $pts = $gd = array();
foreach($group as $key => $value) {
$name[$key] = $value['name'];
$pts[$key] = $value['pts'];
$gd[$key] = $value['gd'];
}
array_multisort($name, SORT_ASC, $pts, SORT_DESC, $gd, SORT_DESC, $group);
}
ksort($arraysByGroup);
print_r($arraysByGroup);
Solution 2:[2]
Let's check
this is my array:
$array = array( array("name" => "SUNDERLAND", "pts" => "2", "gd" => "-4", "group" => "A"),
array("name" => "NEWCASTLE", "pts" => "2", "gd" => "-3", "group" => "C"),
array("name" => "STOKE CITY", "pts" => "2", "gd" => "-2", "group" => "B"),
array("name" => "WATFORD", "pts" => "3", "gd" => "-2", "group" => "A"),
array("name" => "TOTTENHAM", "pts" => "3", "gd" => "-1", "group" => "B"),
array("name" => "CHELSEA", "pts" => "4", "gd" => "-5", "group" => "C"),
array("name" => "NORWICH", "pts" => "4", "gd" => "-3", "group" => "D"),
array("name" => "WEST BROM", "pts" => "4", "gd" => "-4", "group" => "D")
);
this is my result:
Array
(
[A] => Array
(
[0] => Array
(
[name] => SUNDERLAND
[pts] => 2
[gd] => -4
[group] => A
)
[1] => Array
(
[name] => WATFORD
[pts] => 3
[gd] => -2
[group] => A
)
)
[B] => Array
(
[0] => Array
(
[name] => STOKE CITY
[pts] => 2
[gd] => -2
[group] => B
)
[1] => Array
(
[name] => TOTTENHAM
[pts] => 3
[gd] => -1
[group] => B
)
)
[C] => Array
(
[0] => Array
(
[name] => CHELSEA
[pts] => 4
[gd] => -5
[group] => C
)
[1] => Array
(
[name] => NEWCASTLE
[pts] => 2
[gd] => -3
[group] => C
)
)
[D] => Array
(
[0] => Array
(
[name] => NORWICH
[pts] => 4
[gd] => -3
[group] => D
)
[1] => Array
(
[name] => WEST BROM
[pts] => 4
[gd] => -4
[group] => D
)
)
)
In group A I need DESC by pts - there is ASC In group B the same thing In group C & D results are ok
Solution 3:[3]
You probably don't need this anymore, but to help someone looking for something similar, this is how I would solve this ordering issue.
// data
$my_array = array(
array( 'name' => 'SUNDERLAND','pts'=> 2, 'gd' => -4, 'group' => 'A' ),
array( 'name' => 'NEWCASTLE', 'pts' => 2, 'gd' => -3, 'group' => 'C' ),
array( 'name' => 'STOKE CITY', 'pts' => 2, 'gd' => -2, 'group' => 'B' ),
array( 'name' => 'WATFORD', 'pts' => 3, 'gd' => -2, 'group' => 'A' ),
array( 'name' => 'TOTTENHAM', 'pts' => 3, 'gd' => -1,'group' => 'B'),
array( 'name' => 'CHELSEA', 'pts' => 4, 'gd' => -5, 'group' => 'C' ),
array( 'name' => 'NORWICH', 'pts' => 4, 'gd' => -3, 'group' => 'D' ),
array( 'name' => 'WEST BROM','pts' => 4,'gd' => -4, 'group'=> 'D' )
);
// sorting by criterias (group; points and gd);
usort( $my_array, function( $a, $b ) {
if ( $a['group'] === $b['group'] ) {
if ( $a['pts'] === $b['pts'] ) {
return $a['gd'] < $b['gd']; // order by gd
} else {
return $a['pts'] < $b['pts']; // order by points
}
}
return $a['group'] > $b['group']; // order by group
});
// Creating a new array with only desired data.
$final = [];
foreach ( $my_array as $team ) {
if ( empty( $final[ $team['group'] ] ) ) $final[ $team['group'] ] = [];
array_push( $final[ $team['group'] ], $team['name'] );
}
print_r( $final );
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | FuzzyTree |
| Solution 2 | Lilit Tarposhian |
| Solution 3 | Léo Muniz |
