Perl根据内容重新排序哈希数组

时间:2016-06-23 15:38:34

标签: arrays perl hash

有一个哈希数组,我希望能够对它们进行重新排序,将我发现的第一个匹配条件的条目移动到数组中的第一个条目。

使用List::Utils第一种方法我可以确定我想成为数组中的第一个条目。如何将找到的条目作为AoH中的第一个元素?

@Borodin

数据的示例:

CAT1 => 'Foo', CAT2 => 'BAR', TITLE='test1',
CAT1 => 'BAZ', CAT2 => 'BAR', TITLE='test2',
.....

它有很多条目。我希望找到第一个条目(可能有多个条目)CAT1 = BAZ和CAT2 = BAR并将其移动到AoH中的第一个项目。

2 个答案:

答案 0 :(得分:2)

如果没有真实的样本数据,很难提供帮助。

您可以根据使用Perl的sort运算符计算的任何条件对列表的值进行排序,该运算符将表达式或块作为其第二个参数

图书馆List::UtilsBy提供了运营商sort_by等,如果排序标准很复杂,可能会提供速度优势


这会设置您提供的数据并使用Data::Dump

转储它

然后我使用了来自List::MoreUtilsfirst_index,它找到了符合条件的数组的第一个元素的索引

$_->{CAT1} eq 'BAZ' and $_->{CAT2} eq 'BAR'

然后unshiftsplice一起删除该元素并将其放在数组的前面。检查$i是否为零以避免移动已在数组开头的项目

最后,对dd的另一次调用显示匹配的项目已被移动

use strict;
use warnings 'all';

use List::MoreUtils 'first_index';
use Data::Dump;

my @data = (
    {
        CAT1  => 'Foo',
        CAT2  => 'BAR',
        TITLE => 'test1',
    },
    {
        CAT1  => 'BAZ',
        CAT2  => 'BAR',
        TITLE => 'test2',
    }
);

dd \@data;

my $i = first_index {
    $_->{CAT1} eq 'BAZ' and $_->{CAT2} eq 'BAR'
} @data;

die if $i < 0;
unshift @data, splice @data, $i, 1 unless $i == 0;

dd \@data;

输出

[
  { CAT1 => "Foo", CAT2 => "BAR", TITLE => "test1" },
  { CAT1 => "BAZ", CAT2 => "BAR", TITLE => "test2" },
]
[
  { CAT1 => "BAZ", CAT2 => "BAR", TITLE => "test2" },
  { CAT1 => "Foo", CAT2 => "BAR", TITLE => "test1" },
]

答案 1 :(得分:0)

将第一个匹配条目移至开头:

use List::MoreUtils qw( first_index );

my $i = first_index { matches($_) } @aoh;
unshift @aoh, splice(@aoh, $i, 1);

将所有匹配的条目移至开头:

use sort 'stable';
@aoh = 
   sort {
      my $a_matches = matches($a);
      my $b_matches = matches($b);
      ( $a_matches ? 0 : 1 ) <=> ( $b_matches ? 0 : 1 )
   } 
      @aoh;