简体   繁体   English

如何在Perl上对值的自定义哈希值进行排序

[英]How to sort this custom hashes of hashes in perl on the value

I am facing an issue with the sort functionality on my Application. 我在我的应用程序上遇到排序功能问题。 I need to sort my Hash of hashes on the lname key under the instructors . 我需要在instructors下的lname键上对lname进行排序。 The legacy application is written in Perl. 遗留应用程序是用Perl编写的。

Here is the dump of the Hash which i need to sort. 这是我需要排序的哈希的转储。

$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'
    };

The instructors key in the above structure can be empty as well. 上述结构中的教师键也可以为空。 For Example: 例如:

$VAR1 = {
      'instructors' => [],
      'id' => '1237058',
      'XXX' => {
                  'name' => 'Fall 2015 MFT Master 695',
                },
      'YYY' => '45'
    };

In my application, Users have an option to sort the column based on instructor names. 在我的应用程序中,用户可以选择根据讲师姓名对列进行排序。 So when user sorts by ascending order, the application should show rows which have instructors are empty at the start and then show the rest of the rows in which each row has the instructor names sorted in ascending order. 因此,当用户按升序排序时,应用程序应显示在开始时教师为空的行,然后显示其余各行的教师姓名按升序排列的其余行。 Vice versa for Descending Order. 反之亦然。

This is the code which I have tried until now. 这是我到目前为止尝试过的代码。

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'}};

}

How do I get this @sorted hash affect the order of rows in @$course_sections . 我如何获得此@sorted哈希值会影响@$course_sections的行顺序。 Let me know if there is any easier way to do it. 让我知道是否有更简单的方法可以做到这一点。

Thanks in Advance. 提前致谢。

You need to replace each instructors array ref with the sorted version that you created in your foreach loop. 您需要用在foreach循环中创建的排序版本替换每个instructors数组ref。 That way you get the instructors of each individual row sorted. 这样,您就可以对每一行的讲师进行排序。 Then you can sort the whole $course_sections by the name of the first instructor of each row. 然后,您可以按每行的第一位讲师的姓名对整个$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
];

Make sure to replace undef values with empty strings so the cmp doesn't blow up. 确保用空字符串替换undef值,以免cmp We shouldn't do $_->{'instructors'}->[0]->{'lname'} // q{} because autovivification might create a bunch of empty stuff in our data structure. 我们不应该执行$_->{'instructors'}->[0]->{'lname'} // q{}因为自动生存可能会在我们的数据结构中产生大量空白。

Here's your example data pulled together: 这是您的示例数据汇总在一起:

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'
    }
];

And this is the output, dumped with Data::Printer. 这是输出,并通过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
    }
]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM