Perl 如何从具有2个引用的数组哈希中删除重复值

Perl 如何从具有2个引用的数组哈希中删除重复值,perl,Perl,我有一个数组的散列。散列的键是$duration和$attr。我想按降序排序$b$a,只删除那些持续时间相等的重复值。在代码段中,这些应该是流: 'h264/AVC,1080p24/1.001(16:9)&'AC3,英语,多通道,48kHz' 使用duration'26'但不使用$duration'2124'和'115'的重复值 删除重复项的例子数不胜数,我尝试了所有我能找到的方法来满足我的需要,但没有成功。我的解决方法应该是什么。谢谢 my ( %recordings_by_dur_attr

我有一个数组的散列。散列的键是
$duration
$attr
。我想按降序排序
$b$a
,只删除那些持续时间相等的重复值。在代码段中,这些应该是流:

'h264/AVC,1080p24/1.001(16:9)&'AC3,英语,多通道,48kHz'
使用duration
'26'
但不使用$duration
'2124'
'115'
的重复值

删除重复项的例子数不胜数,我尝试了所有我能找到的方法来满足我的需要,但没有成功。我的解决方法应该是什么。谢谢

my ( %recordings_by_dur_attr ) = ();

push( @{ $recordings_by_dur_attr{ $duration }{ $attr } }, @stream );

print Data::Dumper->Dump( [\%recordings_by_dur_attr] );
结果:

$VAR1 = {
      '2124' => {
                  '00300.mpls, 00-35-24' => [
                                              '',
                                              'h264/AVC, 480i60 /1.001 (16:9)',
                                              'AC3, English, stereo, 48kHz'
                                            ]
                },
      '50' => {
                00021.mpls, 00-00-50' => [
                                            '',
                                            'h264/AVC, 1080p24 /1.001 (16:9)',
                                            'AC3, English, multi-channel, 48kHz'
                                          ]
              },
      '6528' => {
                  '00800.mpls, 01-48-48' => [
                                              '',
                                              'Chapters, 18 chapters',
                                              'h264/AVC, 1080p24 /1.001 (16:9)',
                                              'DTS, Japanese, stereo, 48kHz',
                                              'DTS Master Audio, English, stereo, 48kHz',
                                              'DTS, French, stereo, 48kHz',
                                              'DTS, Italian, stereo, 48kHz',
                                              'DTS, German, stereo, 48kHz',
                                              'DTS, Spanish, stereo, 48kHz',
                                              'DTS, Portuguese, stereo, 48kHz',
                                              'DTS, Spanish, stereo, 48kHz',
                                              'DTS, Russian, stereo, 48kHz'
                                            ]
                },
      '26' => {
                '01103.mpls, 00-00-26' => [
                                            '',
                                            'h264/AVC, 1080p24 /1.001 (16:9)',
                                            'AC3, English, multi-channel, 48kHz'
                                          ],
                '01102.mpls, 00-00-26' => [
                                            '',
                                            'h264/AVC, 1080p24 /1.001 (16:9)',
                                            'AC3, English, multi-channel, 48kHz'
                                          ],
                '00011.mpls, 00-00-26' => [
                                            '',
                                            'h264/AVC, 1080p24 /1.001 (16:9)',
                                            'AC3, English, multi-channel, 48kHz'
                                          ]
              },
      '115' => {
                 '00304.mpls, 00-01-55' => [
                                             '',
                                             'h264/AVC, 480i60 /1.001 (16:9)',
                                             'AC3, English, stereo, 48kHz'
                                           ]
               }
    };
重复结构

 '',
'h264/AVC, 1080p24 /1.001 (16:9)',
'AC3, English, multi-channel, 48kHz'
需要删除重复结构的结果:

$VAR1 = {
      '2124' => {
                  '00300.mpls, 00-35-24' => [
                                              '',
                                              'h264/AVC, 480i60 /1.001 (16:9)',
                                              'AC3, English, stereo, 48kHz'
                                            ]
                },
      '50' => {
                00021.mpls, 00-00-50' => [
                                            '',
                                            'h264/AVC, 1080p24 /1.001 (16:9)',
                                            'AC3, English, multi-channel, 48kHz'
                                          ]
              },
      '6528' => {
                  '00800.mpls, 01-48-48' => [
                                              '',
                                              'Chapters, 18 chapters',
                                              'h264/AVC, 1080p24 /1.001 (16:9)',
                                              'DTS, Japanese, stereo, 48kHz',
                                              'DTS Master Audio, English, stereo, 48kHz',
                                              'DTS, French, stereo, 48kHz',
                                              'DTS, Italian, stereo, 48kHz',
                                              'DTS, German, stereo, 48kHz',
                                              'DTS, Spanish, stereo, 48kHz',
                                              'DTS, Portuguese, stereo, 48kHz',
                                              'DTS, Spanish, stereo, 48kHz',
                                              'DTS, Russian, stereo, 48kHz'
                                            ]
                },
      '26' => {
                '00011.mpls, 00-00-26' => [
                                            '',
                                            'h264/AVC, 1080p24 /1.001 (16:9)',
                                            'AC3, English, multi-channel, 48kHz'
                                          ]
              },
      '115' => {
                 '00304.mpls, 00-01-55' => [
                                             '',
                                             'h264/AVC, 480i60 /1.001 (16:9)',
                                             'AC3, English, stereo, 48kHz'
                                           ]
               }
    };
后处理

for my $duration ( sort { $b <=> $a } keys %recordings_by_dur_attr ) {
   for my $attr ( keys $recordings_by_dur_attr{ $duration }  ) {

       #Remove duplicate structures

        my @stream = @{ $recordings_by_dur_attr{ $duration }{ $attr } };
        my ( $mpls, $hms ) = ( $attr =~ /(\d+\.mpls), (\d+-\d+-\d+)$/ );
        for ( my $i = 1;  $i < @stream; $i++ ) {

        #extract info from each stream

        }
    }
}
我的$duration(按\u dur\u attr对{$b$a}键%recordings进行排序){
对于my$attr(键$recordings\u by\u dur\u attr{$duration}){
#删除重复的结构
my@stream=@{$recordings\u by_dur_attr{$duration}{$attr};
我的($mpls,$hms)=($attr=~/(\d+\.mpls),(\d+-\d+-\d+$/);
对于(我的$i=1;$i<@stream;$i++){
#从每个流中提取信息
}
}
}
步骤:

    1. Traverse the hash.
    2. if ref $key eq "ARRAY"
       then 
       1. my `@temp = uniq(@{$hash->{$key}})`;
       2. $var = undef;
       3. $var = \@temp;
       Else
       1. Traverse the hash.
    3. Else
       1. next;

表达式
$seen{$candidate}++
对于查找重复项非常有用。当它返回true时,
$candidate
先前已被看到。最常用的用法如下:

my @uniq = grep !$seen{$_}++, @list;
我没有构建一个要保留的元素键列表,而是将条件反转为构建一个要删除的元素键列表

sub id { pack 'N/(N/a*)', @{ $_[0] } }

for my $recordings_by_attr (values(%recordings_by_dur_attr)) {
   my %seen;
   delete @{$recordings_by_attr}{
       grep $seen{id($recordings_by_attr->{$_})}++,
        sort
         keys %$recordings_by_attr
   };
}

排序决定删除哪些重复项。如果您不在乎哪个,您可以在我排序后删除
排序

,并删除我要计数的重复项,另外处理每个播放列表中的每个流(例如获取语言),并从$attr中提取mpls编号和时间戳。我很抱歉。显然我误解了你的要求。我发布了应该被视为重复结构的内容-多个流。我想将这些多个播放流与每个播放列表进行比较,并删除重复的播放流,重复的播放流具有相同的$duration。我想删除那些重复的结构,因为它们是相同的播放列表,从这个意义上说,它们是冗余的。我的最终目标是自动化提取编解码器流的过程,如果存在许多这样的流,这将非常耗时。在某些情况下,我说的是20-30 playlists.btw,
$hashref
对于一个实际包含哈希引用的变量来说是一个非常糟糕的名称,但是命名一个哈希
%hashref
是非常糟糕的。非常感谢ikegami。我更改了错误的命名以符合您的建议,显然这是解决方案,但我不断遇到一个错误:
无法使用字符串$attr作为数组引用,而在sub-id{pack'N/(N/a*),@$}
处使用“strict ref”。我是不是错过了什么是的!!!你让我开心。无限感谢。我的拼图中缺少的部分是
sub-id{pack'N/(N/a*),@{$[0]}
,这是解决我的问题的关键,因为我已经尝试了
grep$多次看到{$}++
。再次感谢。你需要一个函数(数学意义上的)F,其中F(a)eq F(B)表示所有重复的a,B;其中F(A)ne F(B)表示所有不同的A,B。值是什么并不重要,只要它满足上述定义<如果数组中的值不能包含换行符,则grep$seen{join“\n”,@$\u0},可以,但是使用了一种处理每个字符串的解决方案。