Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Looking for function similer to member() in SKILL

by riz (Initiate)
on Jun 21, 2005 at 08:10 UTC ( #468588=perlquestion: print w/replies, xml ) Need Help??

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

Hi,
Perhaps those who are familier with SKILL language can understand my question well. I am looking for a PERL function which is equalent to SKILL's member().

I have an array lets say @arr = qw/one two three/
and then I am reading a file and get only those lines matching the elements of my array. I want to avoid foreach loop over while <> (as both @arr & file are big). It would be less time consuming if i read the file only once and get the matched lines containing members from @arr.

Thanks,
riz.
  • Comment on Looking for function similer to member() in SKILL

Replies are listed 'Best First'.
Re: Looking for function similer to member() in SKILL
by Zaxo (Archbishop) on Jun 21, 2005 at 08:38 UTC

    Something like this?

    @arr = map {qr/\Q$_\E/} @arr; my @keepers = do { local $" = '|'; grep { m/@arr/ } <>; };
    Efficiency can be improved by ordering @arr by commonest words first. m// is a stringifying interpolated quote-like operator, so $" gets inserted between array elements, making a regex alternation.

    If that's too slow, you can make a hash with @arr as keys and look for existence over a split of your input lines.

    my (%hsh, @keepers); @hsh{@arr} = (); while (<>) { push @keepers, $_ if grep {exists $hsh{$_}} split; }
    That contains a number of tricks you may not know; default args for split, hash slice, two different $_'s in a statement.

    Reading the file line by line is not a big drag on speed if you get to only read the file once.

    After Compline,
    Zaxo

      That's a very cool way of solving this problem, I learned quite a bit from reading it. I noticed that this returns lines that contain at least one element in @arr. I made a simple modification to the second algorithm to only return lines that have all elements in @arr. The OP didn't specify if he meant one or all array elements, so here's my modification for brevity's sake.

      my (%hsh, @keepers); @hsh{@arr} = (); while (<>) { push @keepers, $_ unless grep {!exists $hsh{$_}} split; }
      Thanks for enlightening me with that code sample Zaxo
      Zaxo,
      I wonder what riz meant by "both @arr & file are big"? I know that demerphq has provided patches to bleed perl for alternation in regexen, but this can get slow quickly in 5.8.x. Ok - let's assume that for some reason a hash isn't an option (order is important) and memory consumption is at a premium already. Is there a way to make it any faster?
      I have no idea how well this scales but my guess is it is a failed attempt. I doubt the reciprocal of this solution (indexing file offsets instead) would have been any better. It was a fun experiment anyway.

      Cheers - L~R

        Hello all,
        Thank to all. I found out that there is a perl module member.pm available which should perform the same function as Skill language member().
        Again I am stuck in the loop. I want to print the pair of integer values for only the member of @arr e.g. in this case the pair integer values for Stack3 and Stack5 should be printed. Somehow the member function is reading only the first element of my array.Somebody advice where I am doing wrong?

        Here is my code;
        And here is the file;

        20050627 Edit by ysth: code tags

Re: Looking for function similer to member() in SKILL
by jbrugger (Parson) on Jun 21, 2005 at 08:32 UTC
    I assume you mean skill?
    I'd use a hashtable in stead of an array, and let the key be the match you need, and the value 1.
    open (FH,"filename here") or die; while ( my $line = <FH> ) { if ( $youhash->{$line} ) { #he, a match! } }
    "We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.
Re: Looking for function similer to member() in SKILL
by robartes (Priest) on Jun 21, 2005 at 08:24 UTC

    You'll have to explain what you want to do a bit better, I'm afraid. Most of us are not proficient in SKILL (at least I'm not -- I had not heard of it before your post :) ), and it's not quite clear what you want to do from the rest of your post. Could you clarify a bit?

    CU
    Robartes-

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://468588]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (2)
As of 2022-09-25 04:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer my indexes to start at:




    Results (116 votes). Check out past polls.

    Notices?