0
votes

I am using two arrays (one that holds keys and one that holds values) to build a hash in Perl. I need to count and delete the repeated key/value pairs so that I have a unique hash. Then I have to build a hash of hashes of the form: ((key,value), count).

I am using this line to build the hash from the arrays.

@hash{@keys} = @values;

This will keep repeated key/value pairs in the hash which I do not want. Any help in creating the hash of hashes is appreciated. Thanks.

2
Hash slicing (the thing you're doing) is a great way to zip two ordered arrays together, but I don't think it's a good fit for the problem you're trying to solve. - Mathias R. Jessen
@Mathias R. Jessen Any suggestions for a better approach? - CS student
Not 100% sure about your intended hash of hash structure (((key,value), count)). A Key/Value pair can't be a hash key, has to be a string - Mathias R. Jessen
I just need some way to count the number of occurrences for a key/value pair @MathiasR.Jessen - CS student
Can you give some example data and a desired result? Key collision mean you can't slice them together, because that will overwrite - Sobrique

2 Answers

0
votes

You can use a hash of hashes, where each key hash a subhash of the form value => count.

#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;

my @keys   = qw( k1 k1 k1 k2 k2 k3 k4 k4 k5);
my @values = qw( v1 v2 v2 v3 v4 v5 v6 v6 v7 );

my %hash;
for my $idx (0 .. $#keys) {
    $hash{ $keys[$idx] }{ $values[$idx] }++;
}

print Dumper \%hash;
0
votes

Let's say you arrays look like this:

my @keys   = qw/a b c a a/;
my @values = qw/1 2 3 4 1/;

It's as easy as a simple for loop:

for ($i = 0; $i < scalar @keys; $i++) {
    $hash{$keys[$i]}{$values[$i]} += 1;
}

You can then iterate over the inner values (the count) with a nested loop:

foreach my $key (keys %hash) {
    while (my ($value, $count) = each %{ $hash{$key} } ) {
        print "$key : $value = $count\n";
    }
}

Which would produce:

c : 3 = 1
a : 4 = 1
a : 1 = 2
b : 2 = 1

You can sort the keys if you want to:

foreach my $key (sort keys %hash) {
    # same as before 
}

To get

a : 4 = 1
a : 1 = 2
b : 2 = 1
c : 3 = 1