Reputation: 6350
For creating a Json file i am pushing a hashes in an array but the values are getting duplicated now i don't want to add those hashes which are already in the array.
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**
}
}
So from the below array of hashes i don't want duplicate ones
[
{
"accessCode": "NQ",
"bcode": "PD",
"corporateId": "12"
},
{
"accessCode": "NQ",
"bcode": "CI",
"corporateId": "2122121"
},
{
"accessCode": "NQ",
"bcode": "CI",
"corporateId": "2122121"
},
{
"accessCode": "CD",
"bcode": "PD",
"corporateId": "12"
},
The final ooutput from the code changes should give a result like below :
[
{
"accessCode": "NQ",
"bcode": "PD",
"corporateId": "12"
},
{
"accessCode": "NQ",
"bcode": "CI",
"corporateId": "2122121"
},
{
"accessCode": "CD",
"bcode": "PD",
"corporateId": "12"
},
Or is there any way we can remove duplicate hashes from the array.
Upvotes: 0
Views: 66
Reputation: 386696
Checking !$seen{$key}++
is a common way of identifying the first of duplicates. For example,
my %seen;
my @uniques = grep { !$seen{$_}++ } @items;
This can be unrolled into a foreach loop.
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,
};
}
}
To save memory, you could even replace
next if $seen{ $corp_id->{s_id} }{ $corp_id->{c_id} }{ $rcode }++;
with
next if $seen{ join ":", $corp_id->{s_id}, $corp_id->{c_id}, $rcode }++;
but that assumes none of the three fields can contain :
.
Upvotes: 0
Reputation: 4997
It would be ineficient to check the whole array before pushing or remove duplicates afterwards. So you need to keep track what data you have pushed already:
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)
just to make it shorter and more readable.
Upvotes: 1