Should I write my own Grep or Index function ?

Discussion in 'Perl Misc' started by Mark, Jul 7, 2005.

  1. Mark

    Mark Guest

    Hi all,

    I tried to find the way to search the first occurence of a string into
    a list (which is a sub-set of a file) in order to know if this string
    occurs at least one time anywhere.

    I've read the perldoc -f grep and perldoc -f index but it seems that
    these two functions does not allow me to do it in a simple way.

    So do I have to write my own index function ?

    I tried something like the following, but it seems that I do not handle
    properly the line I passed to the function:

    #!/usr/bin/perl -w
    #!C:\Perl\bin\perl.exe -w

    use strict;
    use warnings;
    use Benchmark;

    my @f_lines = (<DATA>);
    my $i = "aaaaaef";
    my ($count, $start, $end);

    print "\n$0: String searched is $i\n\n";

    &start_bm;
    $count = grep (/$i/i, @f_lines) ;
    &print_bm("GREP: returned $count, ");

    &start_bm;
    $count = &my_index ("$i",@f_lines) ;
    &print_bm("MY_INDEX: returned $count, ");

    sub my_index() {
    # $_[0]: searched string
    # $_[1]: list

    my $tag = $_[0];
    my @list = $_[1];
    my $n;

    foreach (<@list>) {
    $n = index($_, /$tag/i);
    if ($n) {
    return 1;
    }
    }
    return 0;
    }

    ##
    ## Functions
    ##

    sub start_bm { $start = new Benchmark; }

    sub print_bm() {
    $end = new Benchmark;
    printf $_[0]."%s\n", timestr(timediff($end, $start),'auto');
    }

    ###########################################################################


    TIA for any help,

    MA
    Mark, Jul 7, 2005
    #1
    1. Advertising

  2. Mark

    Dave Weaver Guest

    On 6 Jul 2005 23:46:55 -0700, Mark <> wrote:
    > Hi all,
    >
    > I tried to find the way to search the first occurence of a string into
    > a list (which is a sub-set of a file) in order to know if this string
    > occurs at least one time anywhere.
    >
    > I've read the perldoc -f grep and perldoc -f index but it seems that
    > these two functions does not allow me to do it in a simple way.


    grep() isn't simple? How so?

    > #!/usr/bin/perl -w

    ^^
    Since you 'use warnings' (well done), the -w is unnecessary.

    > #!C:\Perl\bin\perl.exe -w
    >
    > use strict;
    > use warnings;


    A good start!

    > use Benchmark;
    >
    > my @f_lines = (<DATA>);


    There is no __DATA__ section in your script...

    > my $i = "aaaaaef";


    $i is a poor choice of name for this variable. Yes, I'm being picky,
    but proper variable naming is key to writing programs that other
    people can understand. And "other people" includes yourself in 6
    months time!

    > my ($count, $start, $end);
    >
    > print "\n$0: String searched is $i\n\n";
    >
    > &start_bm;

    ^
    You should not use & on subroutine calls unless you require
    the functionality it provides (you do not, in this case).
    See perldoc perlsub for details.

    Better written as:
    start_bm();

    > $count = grep (/$i/i, @f_lines) ;


    What's not simple about that?

    Note that this may not do what you intend if $i has regular
    expression metacharacters in it. In which case you might want:

    $count = grep /\Q$i/i, @f_lines;

    > &print_bm("GREP: returned $count, ");
    >
    > &start_bm;
    > $count = &my_index ("$i",@f_lines) ;
    > &print_bm("MY_INDEX: returned $count, ");
    >
    > sub my_index() {

    ^^
    Here you are specifying a prototype, indicating that my_index() takes
    no arguments. You don't want or need the parentheses here.
    (see: perldoc perlsub for information on prototypes).

    sub my_index {

    > # $_[0]: searched string
    > # $_[1]: list
    >
    > my $tag = $_[0];
    > my @list = $_[1];


    That doesn't do what you think it's doing. $_[1] contains one single
    scalar, in the case of your call above it's the value of $f_lines[0].
    It doesn't (and can't) contain the whole array.

    my ( $tag, @list ) = @_;

    > my $n;
    >
    > foreach (<@list>) {

    ^ ^

    Why the <...> ? This is a glob operator (see: perldoc -f glob) and
    returns a list of filenames. Not what you were intending, I suspect.

    foreach ( @list ) {

    > $n = index($_, /$tag/i);


    This isn't doing what you intended either. The pattern match will
    return either 1 or 0 depending on if a match is found, which will then
    be passed as the 2nd argument to index().

    Perhaps you meant something like:
    return 1 if index $_ , $tag;
    or
    return 1 if /$tag/;

    I'm not really sure what your my_index() function is trying to achieve
    though. Use grep() if you are trying to deterine the existence of
    something within a list.
    Dave Weaver, Jul 7, 2005
    #2
    1. Advertising

  3. "Mark" <> wrote in message
    news:...
    > Hi all,
    >
    > I tried to find the way to search the first occurence of a string into
    > a list (which is a sub-set of a file) in order to know if this string
    > occurs at least one time anywhere.


    [...]

    > I tried something like the following, but it seems that I do not handle
    > properly the line I passed to the function:


    [...]

    > $count = &my_index ("$i",@f_lines) ;


    I don't think this is a problem, but it would be a better style not to use
    quotes in "$i".

    [...]

    > sub my_index() {
    > # $_[0]: searched string
    > # $_[1]: list
    >
    > my $tag = $_[0];
    > my @list = $_[1];


    Here is a problem:
    In your program, the parametr "@f_lines" of the function call "&my_index
    ("$i",@f_lines);" will always be flattened, such that $_[0] = $i, $_[1] =
    $f_lines[0], $_[2] = $f_lines[1], $_[3] = $f_lines[2], etc...

    So assigning $_[1] to @list only gets you the first element of @f_lines.

    I suggest you get the other elements ($_[2] = $f_lines[1], $_[3] =
    $f_lines[2], etc...) as well, for example:

    sub my_index() {
    my $tag = shift;
    my @list = @_;

    >
    > TIA for any help,
    >
    > MA


    --
    Klaus Eichner
    Klaus Eichner, Jul 7, 2005
    #3
  4. Mark <> wrote:

    > I tried to find the way to search the first occurence of a string into
    > a list (which is a sub-set of a file) in order to know if this string
    > occurs at least one time anywhere.
    >
    > I've read the perldoc -f grep and perldoc -f index



    See also your FAQ:

    perldoc -q list

    How can I tell whether a certain element is contained in a list or array?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jul 7, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stefan Siegl
    Replies:
    1
    Views:
    762
  2. komal
    Replies:
    6
    Views:
    1,410
    msalters
    Jan 25, 2005
  3. Matthew Wilson

    How should I use grep from python?

    Matthew Wilson, May 7, 2009, in forum: Python
    Replies:
    5
    Views:
    2,160
    Marco Mariani
    May 7, 2009
  4. Petter Gustad
    Replies:
    13
    Views:
    791
    Xah Lee
    Feb 11, 2011
  5. Tomasz Chmielewski

    sorting index-15, index-9, index-110 "the human way"?

    Tomasz Chmielewski, Mar 4, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    271
    Tomasz Chmielewski
    Mar 4, 2008
Loading...

Share This Page