in reply to Comparing masses in two txt files

In Perl it is very easy to 'slurp' files, and it is a really bad habit to get into. In this case one of the files needs to be slurped so try to make it the smallest. There is actually a hidden loop in the code below - the grep, but if you understand grep, then it does make the code much clearer.

As a Perl beginner you should note that strictures should always be used (use strict; use warnings;), file opens should use the three parameter version and are checked, and that some checking (but not as much as there ought to be) is made on the input data.

use warnings; use strict; my $List1 = <<DATA; .2 .3 .4 DATA my $List2 = <<DATA; .4 .5 .6 DATA open my $in1, '<', \$List1 or die "Failed to open List1: $!"; my @data1 = grep {chomp; length} <$in1>; close $in1; my $hitCount = 0; open my $in2, '<', \$List2 or die "Failed to open List2: $!"; while (<$in2>) { chomp; next unless length; my $data2 = $_; $hitCount += grep {abs ($data2 - $_) <= 0.2} @data1; } close $in2; print "Found $hitCount matches\n";

Prints:

Found 6 matches

Perl reduces RSI - it saves typing

Replies are listed 'Best First'.
Re^2: Comparing masses in two txt files
by johngg (Canon) on Nov 05, 2008 at 21:26 UTC
    I'm a bit puzzled by the use of length in this line.

    my @data1 = grep {chomp; length} <$in1>;

    I would have though you want the chomped data so just pass out $_ instead.

    my @data1 = grep {chomp; $_} <$in1>;

    Maybe I'm missing something obvious.

    Cheers,

    JohnGG

      The grep is there to skip blank lines hence the length. Putting the chomp in the grep in that fashion avoids a map:

      my @data1 = grep length, map chomp, <$in1>;

      You don't "pass out" the value from grep. It tests the result returned for each element of the source list to determine if the element is placed in the output list.


      Perl reduces RSI - it saves typing
        Doh! I must have taken some "stupid" pills with breakfast today :-(

        However, that map chomp, <$in1>; will result in a load of '1's being emitted to the grep denoting the success of the chomps. The whole line should perhaps be

        my @data1 = grep length, map {chomp; $_} <$in1>;

        Obviously, your original line was fine and I'm sorry my buffle-headed senior moment got us into this :-/

        Cheers,

        JohnGG