如果找到重复项,请删除Perl Hash值

时间:2014-06-14 05:59:18

标签: perl hash

我需要一个快速的帮助,我在Unix服务器中使用一些命令,然后用这些命令创建一个哈希。

问题大多数情况下,有重复的值即将到来,我想删除这些哈希的任何重复值。

以下是一个例子:

[randy@server04 ~/scripts]$ perl snmpperl.pl 
$VAR1 = {
    '1b' => [
        'abc_pl',
        'abc_pl',
        'abc_pl',
        'xyz_pl',
        'xyz_pl',
    ],
    '1a' => [
        'abc_pl',
        'abc_pl',
        'abc_pl',
        'abc_pl',
        'xyz_pl',
        'xyz_pl',
    ]

我需要哈希: -

$VAR1 = {
    '1b' => [
        'abc_pl',
        'xyz_pl',
    ],
    '1a' => [
        'abc_pl',
        'xyz_pl',
    ]

2 个答案:

答案 0 :(得分:3)

这是一个相对常见的Perl习惯用法,实际上是在FAQ中解决的,你可以在安装了Perl的任何系统上输入perldoc -q duplicate来找到它。

以下是对常见问题解答中表达的想法的改编:

use strict;
use warnings;
use Data::Dumper;

my %hash = (
  '1b' => [ 'abc_pl', 'abc_pl', 'abc_pl', 'xyz_pl', 'xyz_pl', ],
  '1a' => [ 'abc_pl', 'abc_pl', 'abc_pl', 'abc_pl', 'xyz_pl', 'xyz_pl', ],
);

foreach my $v ( values %hash ) {
  my %seen;
  @$v = grep { !$seen{$_}++ } @$v;
}

print Dumper \%hash;

这可以通过跟踪之前是否已经看到给定散列键的子数组中的任何给定元素来工作。如果没有,请将其传递给grep过滤器。否则,请勿发送。最后,构建到新结构中的所有内容都是数组元素的单个实例。

值得一提的一个细微差别; foreach循环中的“it”变量成为它所代表的元素的别名。因此,在这种情况下,对于循环的每次迭代,$v别名哈希元素,其值包含匿名数组引用。我们简单地用匿名元素替换匿名数组ref的内容。

答案 1 :(得分:3)

use List::MoreUtils 'uniq';

@$_ = uniq @$_ for values %hash;

List::MoreUtils

替换uniq
sub uniq (@) {
    my %seen;
    grep !$seen{$_}++, @_;
}