Hello AhmedABdo,
There are many many ways on solving your problem, one way could be:
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @array = ("world", "today", "is nice"); my %hash = ( 0 => "Hello", 1 => "world", 2 => "today", 3 => "is" , 4 => "nice" ); my @hashValues = values %hash; print Dumper \@hashValues; use List::Compare; my $lc = List::Compare->new(\@hashValues, \@array); my @intersection = $lc->get_intersection; my @union = $lc->get_union; print Dumper \@intersection; __END__ Monks$ perl test.pl $VAR1 = [ 'nice', 'Hello', 'today', 'world', 'is' ]; $VAR1 = [ 'today', 'world' ];
I would recommend to read the List::Compare module.
Be aware in your example that you provided us, the values of the hash is and nice are not one string as in the array so as expected they will not match.
Update: please every time you update your question / reply provide and update so can follow. You have altered your question and my reply is not suitable to you any more. I will post another reply in a few hours when I will get back to my pc.
Update2: An alternative solution to your problem:
my @new_array; while (my ($key, $value) = each %hash) { for (@array) {push @new_array, $key if ($value eq $_);} } __END__ $VAR1 = [ '2', '1' ];
Update3: In case you want your keys sorted:
my @new_array_sorted = sort @new_array; print Dumper \@new_array_sorted; __END__ $VAR1 = [ '1', '2' ];
Update4: Maybe this solution is faster using grep:
my @new_array; while (my ($key, $value) = each %hash) { push @new_array, $key if (grep { /^$value$/ } @array); } __END__ $VAR1 = [ '2', '1' ];
Update5: Maybe map is fast I am not sure though:
my @new_array; while (my ($key, $value) = each %hash) { map { if($value eq $_) { push @new_array, $key } } @array; } __END__ $VAR1 = [ '2', '1' ];
Update6: Maybe smartmatch is fast I am not sure though, but it has been placed as experimental see (The smartmatch family of features are now experimental):
no if $] >= 5.018, "experimental::smartmatch"; #disable warnings while (my ($key, $value) = each %hash) { push @new_array, $key if ($value ~~ @array); } __END__ $VAR1 = [ '2', '1' ];
Update7: I could not resist I benchmark them and here is what I found:
#!/usr/bin/perl use strict; use warnings; use Benchmark qw( timethese cmpthese ) ; no if $] >= 5.018, warnings => "experimental::smartmatch"; my @array = ("world", "today", "is nice"); my %hash = ( 0 => "Hello", 1 => "world", 2 => "today", 3 => "is" , 4 => "nice" ); my @new_array; my $results = timethese(1000000000, { 'map' => benchmarkMap(), 'grep' => benchmarkGrep(), 'foreach' => benchmarkForeach(), 'smartmatch' => benchmarkSmartMatch(), }, 'none'); cmpthese( $results ) ; sub benchmarkSmartMatch { while (my ($key, $value) = each %hash) { push @new_array, $key if ($value ~~ @array); } } sub benchmarkGrep { while (my ($key, $value) = each %hash) { push @new_array, $key if (grep { /^$value$/ } @array); } } sub benchmarkForeach { while (my ($key, $value) = each %hash) { for (@array) {push @new_array, $key if ($value eq $_);} } } sub benchmarkMap { while (my ($key, $value) = each %hash) { map { if($value eq $_) { push @new_array, $key } } @array; } } __END__ Monks$ perl test.pl Rate foreach smartmatch grep map foreach 76569678/s -- -30% -59% -64% smartmatch 109170306/s 43% -- -42% -49% grep 187969925/s 145% 72% -- -13% map 215053763/s 181% 97% 14% --
Please on your next question that you will post on the forum follow the guided lines (How do I post a question effectively?).
Hope this helps.
In reply to Re: Search hash keys using values from array
by thanos1983
in thread Search hash keys using values from array
by AhmedABdo
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |