Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

searching a file

by hotshot (Prior)
on Mar 19, 2002 at 16:51 UTC ( #152771=perlquestion: print w/ replies, xml ) Need Help??
hotshot has asked for the wisdom of the Perl Monks concerning the following question:

A busy day ! (at least for me)

I have an array of strings and a file that is of the format:
str1 value1 str2 value2 ...
both the array and the strings in the file are not necessarly sorted.
I need a quick way to run on this file and get the values for the strings in the array (we shell assume they all exist), I thought about reading the file to an array, sort it and run on it again (I sorted the array too).
Anyone has a better way?

Thanks.

Hotshot

Comment on searching a file
Download Code
Re: searching a file
by PrakashK (Pilgrim) on Mar 19, 2002 at 17:04 UTC
    I am assuming that you want to search using a strn to get the corresponding valuen.

    In that case, a hash is an ideal solution (assuming your file is not too big as to cause memory problems for you). once you have the hash populated, getting a value is as easy as:

    my $value_n = $hash{$str_n};

    /prakash

Re: searching a file
by strat (Canon) on Mar 19, 2002 at 17:07 UTC
    my @list = qw(value1 value2); unless (open (FILE, $filename)){ die("Error in opening $filename: $!\n"); } # if else { while (<FILE>){ chomp($_); # split up to maximal "two columns" by whitespaces my ($str, $val) = split(/\s+/, $_, 2); # search @list for $val if ( grep { $val eq $_ } @list ){ print "$val found\n"; } } # while close (FILE); } # else
    If you don't need $str in your code, write something like this:
    ... while (<FILE>){ chomp($_); # split up to maximal "two columns" by whitespaces my ($val) = ( split(/\s+/, $_, 2) )[1]; # search @list for $val if ( grep { $val eq $_ } @list ){ print "$val found\n"; } } # while } # else

    I haven't tested these codes.

    Best regards,
    perl -le "s==*F=e=>y~\*martinF~stronat~=>s~[^\w]~~g=>chop,print"

      If you find yourself doing a grep inside a loop you essentially have an inefficient solution as you have one loop inside another (n*n) Paying the one off price to genreate a hash lookup table (or better still storing your data in this form) makes for far greater efficiency. An alternative in some instances is to build and compile a matching regex (outside the loop!) and use this in place of the grep/inner loop.

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: searching a file
by tachyon (Chancellor) on Mar 19, 2002 at 17:13 UTC

    If you have key => value pairs then a hash is the way to go:

    my %hash; # get data as hash open FILE, $file or die $!\n; while (<FILE>) { my ($key, $value) = split; $hash{$key} = $value; } close FILE; my %changes = ( 'str1' => 'val1', 'str2' => 'val2' ); # change data in hash (or add new elements) $hash{$_} = $changes{$_} for keys %changes # overwrite old file with modified hash open FILE, ">$file" or die $!; print FILE "$_\t$hash{$_}\n" for keys %hash; close FILE;

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Hi!

      Nice code - especially:

      $hash{$_} = $changes{$_} for keys %changes

      Greetz, Tom.
        If assigning changes in a hash I prefer to do the following
        @hash{keys %changes} = values %changes;
        I believe it does the same thing (unless I'm missing something) as values() returns the hash values in the same order as keys().
        TIMTOWTDI

        broquaint

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (9)
As of 2014-09-22 09:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (185 votes), past polls