Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: assigning arrays as values to keys of hash

by jwkrahn (Monsignor)
on Sep 18, 2018 at 04:28 UTC ( #1222552=note: print w/replies, xml ) Need Help??


in reply to assigning arrays as values to keys of hash

For unique values you probably want to use a hash instead of an array, something like this:

while ( <FILE> ) { my ( $key, $value ) = split; $hash{ $key }{ $value } = (); } print Dumper \%hash;

Replies are listed 'Best First'.
Re^2: assigning arrays as values to keys of hash
by pearllearner315 (Acolyte) on Sep 18, 2018 at 04:36 UTC
    I specifically need a hash of arrays.. any way that's possible?

      Why do you need a hash of arrays? Is this question related to homework? As mentioned by jwkrahn, using a multi-level hash would allow you to readily avoid duplicates.

      I have the current code that works but it doesn't get rid of the duplicates

      The code you posted does not seem to work. When I ran your code, the hash keys contained an entire line of text and the values were undefined array references. When I removed the double quotes from the first argument to split, I was able to get a hash of array references. However, as you mentioned, there are duplicates in the array references.
      #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; my $file = 'file.txt'; open( FILE, '<', $file ) or die $!; my %hash; while ( <FILE> ) { chomp; my $lines = $_; my $key = (split(/ /, $lines))[0]; my $value = (split(/ /, $lines))[1]; push @{ $hash{$key} }, $value; } print Dumper(\%hash); exit;

      There are quite a few ways you could go about removing the duplicates. Here is one way to do it with help from the uniq function of List::Util.

      #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; use List::Util qw/uniq/; my $file = 'file.txt'; open( FILE, '<', $file ) or die $!; my %hash; while ( <FILE> ) { chomp; my $lines = $_; my ($key, $value) = split(/ /, $lines); push @{ $hash{$key} }, $value; } foreach my $key( keys %hash ){ my @array = @{$hash{$key}}; my @uniq_elems = uniq @array; $hash{$key} = \@uniq_elems; } print Dumper(\%hash); exit;

      push-ing each "organ" to an autovivified anonymous array keyed by its "animal" allows preservation of the original order of "organs" as found in the file (if this is of any importance). If preserving original order isn't important, use the simpler two-level hash approach described by others.

      c:\@Work\Perl\monks>perl -wMstrict -le "use autodie; no autodie qw(open close); ;; use List::MoreUtils qw(uniq); ;; use Data::Dump qw(dd); ;; my $file = qq{bird beak\n} . qq{bird beak\n} . qq{bird claw\n} . qq{bird wings\n} . qq{bird feathers\n} . qq{snake fangs\n} . qq{snake scales\n} . qq{snake fangs\n} . qq{snake tail\n} ; print qq{[[$file]]}; ;; open my $fh, '<', \$file or die qq{opening ram file: $!}; ;; my %hash; while (my $line = <$fh>) { my $parsed = my ($animal, $organ) = $line =~ m{ \A ([[:alpha:]]+) \s+ ([[:alpha:]]+) \Z }xmsg; ;; die qq{bad line '$line'} unless $parsed; ;; push @{ $hash{$animal} }, $organ; } ;; close $fh or die qq{closing ram file: $!}; ;; @$_ = uniq @$_ for values %hash; dd \%hash; " [[bird beak bird beak bird claw bird wings bird feathers snake fangs snake scales snake fangs snake tail ]] { bird => ["beak", "claw", "wings", "feathers"], snake => ["fangs", "scales", "tail"], }


      Give a man a fish:  <%-{-{-{-<

      my %unique; while ( <FILE> ) { my ( $key, $value ) = split; $hash{ $key }{ $value } = (); } $_ = [ keys %$_ ] for values %hash; print Dumper \%hash;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1222552]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2019-07-18 02:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?