从Perl数组中删除重复的哈希

时间:2020-01-17 08:04:52

标签: perl

我有如下的perl数组

my @arr = ({
  CONTEXTID => 1230,
  NAME => 'test8824',
  PROVIDERID => 163
}, {
  CONTEXTID => 8824,
  NAME => 'test8824',
  PROVIDERID => 77
}, {
  CONTEXTID => 8824,
  NAME => 'test8824',
  PROVIDERID => 779
}, {
  CONTEXTID => 8824,
  NAME => 'test8824',
  PROVIDERID => 141
}, {
  CONTEXTID => 1230,
  NAME => 'test8824',
  PROVIDERID => 163
})

我想从数组中删除重复的哈希,输出应如下所示:

({
  CONTEXTID => 1230,
  NAME => 'test8824',
  PROVIDERID => 163
}, {
  CONTEXTID => 8824,
  NAME => 'test8824',
  PROVIDERID => 77
}, {
  CONTEXTID => 8824,
  NAME => 'test8824',
  PROVIDERID => 779
}, {
  CONTEXTID => 8824,
  NAME => 'test8824',
  PROVIDERID => 141
}
)

仅当哈希的所有键都匹配时才识别重复项,否则它就不会重复。

3 个答案:

答案 0 :(得分:4)

以下是删除重复项的常见用法:

my %seen;    
my @unique = grep !$seen{$_}++, @strings;

使用字符串比较来确定两个项目是否相同。在我们的情况下,这样做是不会做的(因为那样可以有效地比较哈希的地址,发现它们都是唯一的)。

但是我们可以很容易地概括如下:

my %seen;    
my @unique = grep !$seen{key($_)}++, @items;

我们现在所需要的只是一个函数key,该函数生成一个字符串,使得满足以下条件:

  • key($a) ne key($b),如果认为$a$b不同。
  • key($a) eq key($b),如果$a被认为与$b相同。

在这种情况下,我们可以使用以下内容:

use feature qw( state );

use Cpanel::JSON::XS qw( );

sub key {
   state $encoder = Cpanel::JSON::XS->new->canonical;
   return $encoder->encode($_[0]);
}

答案 1 :(得分:1)

请确认以下物品满足您的要求

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my @result;
my %seen;

my @arr = ({
  CONTEXTID => 1230,
  NAME => 'test8824',
  PROVIDERID => 163
}, {
  CONTEXTID => 8824,
  NAME => 'test8824',
  PROVIDERID => 77
}, {
  CONTEXTID => 8824,
  NAME => 'test8824',
  PROVIDERID => 779
}, {
  CONTEXTID => 8824,
  NAME => 'test8824',
  PROVIDERID => 141
}, {
  CONTEXTID => 1230,
  NAME => 'test8824',
  PROVIDERID => 163
});

foreach my $el ( @arr ) {
    my $k = join('|', @$el{qw/CONTEXTID NAME PROVIDERID/ });
    push @result, $el unless $seen{$k};
    $seen{$k} = 1;
}

print Dumper(\@result);

输出:

$VAR1 = [
          {
            'PROVIDERID' => 163,
            'CONTEXTID' => 1230,
            'NAME' => 'test8824'
          },
          {
            'NAME' => 'test8824',
            'CONTEXTID' => 8824,
            'PROVIDERID' => 77
          },
          {
            'CONTEXTID' => 8824,
            'PROVIDERID' => 779,
            'NAME' => 'test8824'
          },
          {
            'NAME' => 'test8824',
            'CONTEXTID' => 8824,
            'PROVIDERID' => 141
          }
        ];

答案 2 :(得分:0)

在其中一个stackoverflow答案中,我得到了适用于我的解决方案,我不记得最初的帖子思想了。

 my %seen;
 my @array;
 @array =  grep { my $e = $_; my $key = join '___', map { $e->{$_}; } sort keys %$_;!$seen{$key}++ } @array;

将href数组放入数组变量中,返回的数组将具有唯一的哈希值。