Как отсортировать эти пользовательские хэши в 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
    }
]
Другие вопросы по тегам