Функция Usort для сортировки и группировки
У меня есть этот массив.
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
)
)
Я должен отсортировать и сгруппировать элементы этого массива по некоторым критериям.
В этой же группе первым ИМЯ является имя с большим параметром pts (параметр DESC by pts). Если параметры pts одинаковы по параметру gd (DESC по параметру gd)
Названия команд с одной группой вместе.
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
в этот момент я могу отсортировать по pts и gd следующим образом:
<?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);
?>
Пожалуйста, помогите объединить по группам, а затем в каждой группе порядок по очкам и GD. (В конечном итоге мне нужно показать название группы и название команды!
A
WATFORD
SUNDERLAND
B
TOTTENHAM
STOKE CITY
C
CHELSE
NEWCASTLE
D
NORWICH
WEST BROM
3 ответа
Я хотел бы использовать array_multisort
вместо usort
за это. Сначала сгруппируйте строки по ключу группы. Тогда используйте array_multisort
на каждой группе. Наконец вы можете использовать ksort
если вам нужно, чтобы группы появлялись также в отсортированном порядке.
$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);
Давай проверим
это мой массив:
$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")
);
это мой результат:
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
)
)
)
В группе A I требуется DESC по pts - есть ASC. В группе B то же самое. В группе C & D результаты в порядке.
Возможно, вам это больше не нужно, но чтобы помочь кому-то найти что-то похожее, я бы решил эту проблему с заказом именно так.
// 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 );