在推送到Perl中的数组之前检查哈希值

时间:2019-03-20 19:12:48

标签: perl

为了创建Json文件,我正在将哈希放入数组中,但是现在值已重复,我不想添加数组中已经存在的哈希。

foreach my $corp_id(@{corpId}) {
    foreach my $rcode(@{$brands_map->{$corp_id->{s_brand}}}) {
            my corpIdAccessCode;
            $corpIdAccessCode->{accessCode} = $corp_id->{s_id};
            $corpIdAccessCode->{corporateId} = $corp_id->{c_id};
            $corpIdAccessCode->{bcode} = $rcode;
            push @{$accessCode_array} ,$corpIdAccessCode; **// Here before pushing to array i want to have a check wheather $corp_id->{s_id}, $corp_id->{c_id} and  $rcode already exists or not in the accessCode_array**
    }
}

因此,从下面的哈希数组中,我不想重复哈希

[
      {
        "accessCode": "NQ",
        "bcode": "PD",
        "corporateId": "12"
      },
      {
        "accessCode": "NQ",
        "bcode": "CI",
        "corporateId": "2122121"
      },
      {
        "accessCode": "NQ",
        "bcode": "CI",
        "corporateId": "2122121"
      },
      {
        "accessCode": "CD",
        "bcode": "PD",
        "corporateId": "12"
      },

代码更改的最终输出应如下所示:

[
      {
        "accessCode": "NQ",
        "bcode": "PD",
        "corporateId": "12"
      },
      {
        "accessCode": "NQ",
        "bcode": "CI",
        "corporateId": "2122121"
      },

      {
        "accessCode": "CD",
        "bcode": "PD",
        "corporateId": "12"
      },

或者有什么方法可以从数组中删除重复的哈希。

2 个答案:

答案 0 :(得分:1)

在推送或之后删除重复项之前检查整个数组是不够的。因此,您需要跟踪已经推送的数据:

my $seen;
foreach my $corp_id(@{corpId}) {
    foreach my $rcode(@{$brands_map->{$corp_id->{s_brand}}}) {
            my ($k1, $k2, $k3) = ($corp_id->{s_id}, $corp_id->{c_id}, $rcode);
            if ($seen->{$k1}->{$k2}->{$k3}) {
                next;
            }
            $seen->{$k1}->{$k2}->{$k3} = 1;

            my $corpIdAccessCode;
            $corpIdAccessCode->{accessCode} = $corp_id->{s_id};
            $corpIdAccessCode->{corporateId} = $corp_id->{c_id};
            $corpIdAccessCode->{bcode} = $rcode;
            push @{$accessCode_array} ,$corpIdAccessCode; **// Here before pushing to array i want to have a check wheather $corp_id->{s_id}, $corp_id->{c_id} and  $rcode already exists or not in the accessCode_array**
    }
}

my ($k1, $k2, $k3)只是为了使其更短,更易读。

答案 1 :(得分:0)

检查!$seen{$key}++是识别第一个重复项的常用方法。例如,

my %seen;
my @uniques = grep { !$seen{$_}++ } @items;

这可以展开到foreach循环中。

my %seen;
for my $corp_id (@corpId) {
    for my $rcode (@{ $brands_map->{ $corp_id->{s_brand} } }) {
        next if $seen{ $corp_id->{s_id} }{ $corp_id->{c_id} }{ $rcode }++;

        push @$accessCode_array, {
            accessCode  => $corp_id->{s_id},
            corporateId => $corp_id->{c_id},
            bcode       => $rcode,
        };
    }
}

要节省内存,您甚至可以更换

next if $seen{ $corp_id->{s_id} }{ $corp_id->{c_id} }{ $rcode }++;

使用

next if $seen{ join ":", $corp_id->{s_id}, $corp_id->{c_id}, $rcode }++;

但是假设这三个字段都不能包含: