in reply to Looking for function similer to member() in SKILL

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

Replies are listed 'Best First'.
Re^2: Looking for function similer to member() in SKILL
by redhotpenguin (Deacon) on Jun 21, 2005 at 09:11 UTC
    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
Re^2: Looking for function similer to member() in SKILL
by Limbic~Region (Chancellor) on Jun 21, 2005 at 14:33 UTC
    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

        Anonymous Monk,
        Please read Writeup Formatting Tips to make your posts clearer in the future. Additionally, you may want to look at perlstyle or Perltidy to make your code clearer. You should also start using strictures and warnings and possibly even diagnostics as they will help you to find problems on your own.

        Now on to specific problems with your code. The next unless /@arr[$index]/ should be using the $ sigil as you are talking about a single element. In fact, this line makes little sense anyway as you are checking to see if the line matches your array, and then you are checking it again by matching using a regex. There is no need to match twice. Of course, this won't work for a couple of reasons - the first is that you are not chomping the line so it will never match because of a newline at the end. The second is that you aren't even reading the file - your while () { ... } should really be while ( <IN> ) { ... }.

        There are more problems but I think you need to take a step back. Try starting out with the smallest piece of working code you can imagine and build on it checking the result each time. The first time it doesn't do what you expect, look there for the problem. For instance - start out reading a file and printing the contents.

        Cheers - L~R