Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm not on my own computer so I don't have actual code to hand, but I've got a situation where I need to iterate through an array and do something if a number exists in another array. I had loaded the second array into a hash to test with exists while iterating through the first array, but now I realise that the number is not necessarily unique.

How can I set up the second array so that I do not end up doing a for loop within a for loop?

One thing I've been thinking of is storing any repeated numbers in a hash of arrays with the number as key, then if the number exists extract the info and iterate over the hash to extract the information. Is this a right approach?

I'm sorry if this is not clear, I'll be back on my computer later and can provide some code if necessary. Thanks.

  • Comment on finding exists on non unique information

Replies are listed 'Best First'.
Re: finding exists on non unique information
by graff (Chancellor) on Nov 18, 2007 at 08:20 UTC
    Yes, this is not clear. If you have two arrays of numbers, and you are checking whether the numbers in array1 are present in array2, then you just store the array2 numbers as keys of a hash, then iterate over array1 and check whether each value exists as a hash key.

    If some values are repeated in array2, the hash will have only the unique values as keys (there will be fewer hash keys than there are array elements). But why would that be a problem? In your comment about what you've "been thinking of" (making a hash of arrays), you mention some sort of "information" associated with each number, but what is this "information" and where does it come from? The array is just a list of numbers (some of which might appear more than once).

    If it's important to know how many times a given value occurs in array2, just load and use the hash like this:

    my %a2hash; $a2hash{$_}++ for ( @array2 ); for ( @array1 ) { if ( exists( $a2hash{$_} )) { # use the value that matched, and number of matches in @array2 +: do_something( $_, $a2hash{$_} ); } }
    And of course, for any value that is repeated in array1 and happens to match a value found in array2, "do_something()" will happen each time that value comes up.

    If the question is simply "which of the values in array1 are also found in array2?", then a simple hash with array2 values as keys is all you need, regardless of whether the values are repeated.

    Did you maybe leave out some other aspect of the question?

Re: finding exists on non unique information
by bart (Canon) on Nov 18, 2007 at 09:45 UTC
    for my $index (0 .. $#other_array) { push @{$lookup{$other_array[$index]}}, $index; }
    This will create a lookup hash that contains, as hash value, an array with every index in the other array where it has been found.

    So, instead of having to search through the other array for every item, you now immediately have a list of where it was found, so you can jump straight into the action.

    for my $item (@first_array) { if($lookup{$item}) { foreach my $where (@{$lookup{$item}}) { # ... } } }

    I have no idea what your exact data structures look like, but I'm sure you can adapt this idea to your code.