0

我正在尝试按 location_id 对 Perl 中的以下数据结构进行排序。

my $employees = $dbh->selectall_arrayref(qq[
    SELECT name, type, code, emp_cat_id,
           percentage, location_id
    FROM table_1
],{ Slice => {} });
 
for my $row (@$employees) {
   push @{
      $args->{employees}{ $row->{emp_cat_id} }
   }, $row;
}

例子:

123 => [
   {
      percentage  => 0.25,
      code        => "XYZ",
      name        => "John Doe",
      type        => "pt",
      location_id => 001,
      emp_cat_id  => 123

   }
],
555 => [
   {
      percentage  => 0.50,
      code        => "ZZZ"
      name        => "Chris Cringle",
      type        => "ft",
      location_id => 007,
      emp_cat_id  => 555

   },
   {
      percentage  => 0.25,
      code        => "XXX"
      name        => "Tom Thompson",
      type        => "pt",
      location_id => 002,
      emp_cat_id  => 555

   }
]

对于每个 emp_cat_id,我需要该结构以 asc 顺序具有 location_ids。

我尝试了以下方法,但出现“在第 # 行的 void 上下文中无用的排序”或“在第 # 行的标量上下文中无用的排序”错误。

$args->{employees} = sort {
   $a->{location_id} <=> $b->{location_id}
} $args->{employees};

感谢您对理解排序的任何帮助!

4

2 回答 2

1

问题是您正在对数组(参考)进行排序emp_cat_id555然后是123,因此需要取消引用以对这些数组引用进行排序。所以

foreach my $id (keys $args->{employees}) { 
    @{ $args->{employees}{$id} } = sort { 
            $a->{location_id} <=> $b->{location_id} 
        }
        @{ $args->{employees}{$id} } 
}

(使用问题中显示的结构进行测试,此处省略)†</sup>

做这样的事情会007输给7. 这当然是可以解决的,让我知道是否重要。

如果您真的只有密钥,请employees考虑提取$args->{employees}hashref 并使用它。会容易很多

use Storable qw(dclone);

my $employees = dclone $args->{employees};  # need deep copy

†</sup> 哦,这就是全部

use warnings;
use strict;
use feature 'say';
use Data::Dump qw(dd);

my $args = {
    employees => {
        123 => [
            {
                percentage  => 0.25,
                code        => "XYZ",
                name        => "John Doe",
                type        => "pt",
                location_id => 001,
                emp_cat_id  => 123
            }
        ],
        555 => [
            {
                percentage  => 0.50,
                code        => "ZZZ",
                name        => "Chris Cringle",
                type        => "ft",
                location_id => 007,
                emp_cat_id  => 555

            },
            {
                percentage  => 0.25,
                code        => "XXX",
                name        => "Tom Thompson",
                type        => "pt",
                location_id => 002,
                emp_cat_id  => 555

            }
        ]
    }
};

foreach my $id (keys $args->{employees}) {
    @{ $args->{employees}{$id} } = sort {
            $a->{location_id} <=> $b->{location_id}
        }
        @{ $args->{employees}{$id} }
}

dd $args;
于 2021-12-17T06:05:37.157 回答
0

那么,你有一个 hashref,其中每个元素都是 hashref 的 arrayref,应该根据 hashref 内部的键进行排序?

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

my $hashref = {
    123 => [
        {
            percentage  => 0.25,
            code        => "XYZ",
            name        => "John Doe",
            type        => "pt",
            location_id => 001,
            emp_cat_id  => 123
        }
        ],
    555 => [
        {
            percentage  => 0.50,
            code        => "ZZZ",
            name        => "Chris Cringle",
            type        => "ft",
            location_id => 007,
            emp_cat_id  => 555
        },
        {
            percentage  => 0.25,
            code        => "XXX",
            name        => "Tom Thompson",
            type        => "pt",
            location_id => 002,
            emp_cat_id  => 555
        }
        ]
};

foreach my $arrayref (values %$hashref) {
    @$arrayref = sort { $a->{location_id} <=> $b->{location_id} } @$arrayref;
}

print Dumper($hashref);

您缺少的重要部分是取消引用 arrayrefs。@$arrayref而不仅仅是$arrayref.

于 2021-12-17T06:04:50.300 回答