in reply to updated_again: how to loop through hash tables more efficiently

This:

foreach my $k1 (keys %$h1) { my @fields = split /,/, $h1->{$k1}; ... }

... will be faster as ...

while (my ($k1, $v1) = each %$h1) { my @fields = split /,/, $v1; ... }

each fetches a key-value pair in one go, and except in the case of some tied hashes, will generally be faster than fetching a key and then looking up the value. Both of your hash loops could be optimised this way.

I have a vague feeling that your two loops could be separated out. Hmmm... I'll have a think about it...

Update... this works...

use 5.010; use strict; sub read_hash { my $data = shift; open my $fh, '<', \$data; my %hash; while (<$fh>) { chomp; my ($key,$value)=split /,/, $_, 2; $hash{$key}=$value; } return \%hash; } my $h1 = read_hash(<<'DATA'); k_a1,val_a1,val_a2,val_a3 k_a2,val_a4,val_a5 DATA my $h2 = read_hash(<<'DATA'); k_b1,val_a1 k_b2,val_a2 k_b3,val_a3 k_b4,val_a4 k_b5,val_a5 DATA my %tmp; while (my ($k, $v) = each $h1) { push @{ $tmp{$_} }, $k for split /,/, $v } while (my ($k, $v) = each $h2) { push @{ $tmp{$_} }, $k for split /,/, $v } for (values %tmp) { next if @$_ < 2; say join ',', @$_ }

If you want the lines output in the same order as your original example, then replace the last two lines with:

say $_ for sort map { join ',', @$_ } grep { @$_ > 1 } values %tmp;
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Replies are listed 'Best First'.
Re^2: how to loop through hash tables more efficiently
by lrl1997 (Novice) on Sep 17, 2012 at 22:23 UTC

    Thanks. It does run very fasta, but not the format I want.

    I'd like to have output with KEY and VALUE from hash2 then followed by KEY from hash1,all three are separated by tab?

      Then why didn't you show that in your original question?

      for (sort keys %tmp) { next if @{$tmp{$_}} < 2; say join "\t$_\t", reverse @{ $tmp{$_} }; }
      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re^2: how to loop through hash tables more efficiently
by Anonymous Monk on Sep 17, 2012 at 21:17 UTC

    will generally be faster than fetching a key and then looking up the value.

    microscopically faster

      Indeed; the real speed gain comes from the iterator-like workings of each -- no need to build a list of keys to feed to foreach before even starting the loop (and at 20k keys, that costs quite a bit).