There are a variety of ways of looking at this problem, however, in playing with it, I stumbled because I wouldn't figure out your intent. Looking at your code snippets, I see that each of them is four nested loops! This absolutely won't scale. You state that you believe your way is slow, but I would suggest that you prove your way is slow before continuing. If you have a small data set, it might still be okay.

Further, I still don't know exactly what you're trying to accomplish. I wrote the following test program which, from what I can tell, mimics what you're trying to do, but it still doesn't tell me why you're trying to do it:

use strict; use Data::Dumper; my @found = map { {ID=>$_} } qw( abC e8q xxx 11m ); my $matched = 0; my %manager = ( 1 => { bob => { members => [qw{ abc def gdF }] } }, 7 => { alice => { members => [qw{ 5hg 8DF 9iw }] }, charlie => { members => [qw{ 2je e8q 11M }] } } ); foreach my $id (keys %manager){ foreach my $manager (keys %{$manager{$id}}){ for my $i (0..$#{$manager{$id}{$manager}{'members'}}){ my $index=0; foreach my $emp (@found){ if ($emp->{'ID'}=~/$manager{$id}{$manager}{'members'}[$ +i]/i){ splice(@found, $index, 1); print $emp->{'Name'} . "\n"; $matched++;} $index++;}}}} print "Matched: ($matched) ", Dumper \@found;

Give that the first data structure is so complex, I would suggest that your task it to rethink the construction of said structure or to construct another structure that accomplishes the needed task. For example, we see that each manager (Bob, Alice, and Charlie) has an array of members. In you regular expression, you attempt to match this in a case-insensitive manner, but your match will match if an ID is a substring of a member. If you want to make an exact, but case insentive match, perhaps while constructing the complex data structure, you can make those "members" the keys in a hash (while lower-casing them). This allows the following:

@found = grep { ! exists %members{ lc $_->{ID} } } @found;

(This appears to match your logic where the items in the @found array are those items that were not found in the data structure!)

Thus, instead of having four nested loops, we have one pass through a data structure.

Additionally, you could try putting this data in a database and taking advantage of the capabilities inherent their.

In short, there are a variety of ways to deal with your problem, but if you give us a higher level description of what you need to accomplish, we may be better able to help you.

Side note, instead of using splice to get rid of found elements, have you thought about using push to add the "not found" elements onto a different array? The logic would be easier to follow.

if ( $emp->{ID} =~ /$some_regex/i ) { push @emp_found => $emp; print $emp->{'Name'} . "\n"; } else { push @emp_ot_found => $emp; }

Cheers,
Ovid

New address of my CGI Course.
Silence is Evil (feel free to copy and distribute widely - note copyright text)


In reply to Re: splice question (change your data structure) by Ovid
in thread splice question by tbone

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.