Как отсортировать эти пользовательские хэши в perl по значению
Я столкнулся с проблемой с функцией сортировки в моем приложении. Мне нужно отсортировать хэш хэшей на lname
ключ под instructors
, Устаревшее приложение написано на Perl.
Вот дамп хэша, который мне нужно отсортировать.
$VAR1 = {
'instructors' => [
{
'is_placeholder' => 0,
'lname' => 'Lordy',
'name' => 'Daniel Lordy'
},
{
'is_placeholder' => 0,
'lname' => 'Fisher',
'name' => 'Bethy Fisher'
},
{
'is_placeholder' => 0,
'lname' => 'Jaya',
'name' => 'Jennifer Jaya'
},
],
'id' => '1237058',
'XXX' => {
'name' => 'Fall 2015 MFT Master 695',
},
'YYY' => '45'
};
Ключ инструкторов в приведенной выше структуре также может быть пустым. Например:
$VAR1 = {
'instructors' => [],
'id' => '1237058',
'XXX' => {
'name' => 'Fall 2015 MFT Master 695',
},
'YYY' => '45'
};
В моем приложении пользователи могут сортировать столбец по именам инструкторов. Поэтому, когда пользователь сортирует по возрастанию, приложение должно показывать строки с пустыми инструкторами в начале, а затем показывать остальные строки, в которых в каждой строке имена инструкторов отсортированы в порядке возрастания. И наоборот, по убыванию.
Это код, который я пробовал до сих пор.
if( $sort_order eq 'ASC' ) {
foreach my $elem ( @$course_sections ) {
my @sorted = map { $_->[1] }
sort { $a->[0] cmp $b->[0] }
map { [$_->{'lname'}, $_] } @{$elem->{'instructors'}};
}
if( $sort_order eq 'DESC' ) {
foreach my $elem ( @$course_sections ) {
my @sorted = map { $_->[1] }
sort { $b->[0] cmp $a->[0] }
map { [$_->{'lname'}, $_] } @{$elem->{'instructors'}};
}
Как я могу получить это @sorted
хэш влияет на порядок строк в @$course_sections
, Дайте мне знать, если есть более простой способ сделать это.
Заранее спасибо.
1 ответ
Вам нужно заменить каждый instructors
ссылка на массив с отсортированной версией, которую вы создали в своем foreach
петля. Таким образом, вы получаете сортировку инструкторов каждого отдельного ряда. Тогда вы можете отсортировать весь $course_sections
по имени первого инструктора каждого ряда.
# sort the instructors in-place
foreach my $elem (@$course_sections) {
$elem->{'instructors'} = [
map { $_->[1] }
sort { $a->[0] cmp $b->[0] }
map { [ $_->{'lname'}, $_ ] } @{ $elem->{'instructors'} }
];
}
# sort the courses by first instructor
$course_sections = [
map { $_->[1] }
sort { $a->[0] cmp $b->[0] }
map { [ ( $_->{'instructors'}->[0] ? $_->{'instructors'}->[0]->{'lname'} : q{} ), $_ ] }
@$course_sections
];
Не забудьте заменить undef
значения с пустыми строками, поэтому cmp
не взрывается. Мы не должны делать $_->{'instructors'}->[0]->{'lname'} // q{}
потому что автовивификация может создать кучу пустых вещей в нашей структуре данных.
Вот данные вашего примера, собранные вместе:
my $course_sections = [
{
'instructors' => [
{
'is_placeholder' => 0,
'lname' => 'Lordy',
'name' => 'Daniel Lordy'
},
{
'is_placeholder' => 0,
'lname' => 'Fisher',
'name' => 'Bethy Fisher'
},
{
'is_placeholder' => 0,
'lname' => 'Jaya',
'name' => 'Jennifer Jaya'
},
],
'id' => '1237058',
'XXX' => {
'name' => 'Fall 2015 MFT Master 695',
},
'YYY' => '45'
},
{
'instructors' => [],
'id' => '1237058',
'XXX' => {
'name' => 'Fall 2015 MFT Master 695',
},
'YYY' => '45'
}
];
И это вывод, выгруженный с помощью Data::Printer.
\ [
[0] {
id 1237058,
instructors [],
XXX {
name "Fall 2015 MFT Master 695"
},
YYY 45
},
[1] {
id 1237058,
instructors [
[0] {
is_placeholder 0,
lname "Fisher",
name "Bethy Fisher"
},
[1] {
is_placeholder 0,
lname "Jaya",
name "Jennifer Jaya"
},
[2] {
is_placeholder 0,
lname "Lordy",
name "Daniel Lordy"
}
],
XXX {
name "Fall 2015 MFT Master 695"
},
YYY 45
}
]