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

Hi Monks,
I need help in this range finding stuff. My foreach loop is not working correctly. My input looks like this
5893 5985 + LOC645399 645399 7223 7231 - LOC100131533 100131533 7630 9882 - LOC100131533 100131533 10142 11428 + LOC100132836 100132836 12197 13705 - LOC100132070 100132070 14248 15806 - LOC100132865 100132865 16830 17405 - LOC100132865 100132865 18735 19817 + LOC645399 645399 20802 23113 - LOC100132865 100132865
My code is:- $fn = $ARGV[0]; open(FH, "$fn") || die("Cannot open: $!"); for ($i = 5893; $i <=23113; $i++) { $bin = $i += 7704; push @array, $bin ; } while(<FH>) { if($_ =~ /\A(\S+)\s+(\S+)/) { foreach $line(@array){ print "$line\n"; print "$1 $2\n" if $line >= $1 && $line <= $2; } } }
As per above example my array contains values :- 13597,21302, 29007 which is by 3 division of the maximum value 23113 which means a bin size of 3 with size 7704 per bin and then I am trying where my array values fit as per given ranges in my input data.
I expect my output to come something like this in bin range range specified by my first for loop:-
12197 13705 20802 23113
My foreach loop has got a problem. It prints the value multiple times and also my 2nd if condition is not taking the values.
Thanks in advance

Replies are listed 'Best First'.
Re: Problem in Foreach loop
by Ish (Acolyte) on Apr 02, 2009 at 05:16 UTC
    Sorry, I got a bit tied up with something! Try something like this - your data is in an array but otherwise....
    use strict; use warnings; my ($i, @array, $bin, $line); my @input = ( "5893 5985 + LOC645399 645399", "7223 7231 - LOC100131533 100131533", "7630 9882 - LOC100131533 100131533", "10142 11428 + LOC100132836 100132836", "12197 13705 - LOC100132070 100132070", "14248 15806 - LOC100132865 100132865", "16830 17405 - LOC100132865 100132865", "18735 19817 + LOC645399 645399", "20802 23113 - LOC100132865 100132865" ); for ($i = 5893; $i <=23113; $i++) { $bin = $i += 7704; push @array, $bin ; } foreach $line (@input) { $line =~ m/\s*(\d+)\s*(\d+)/; foreach my $bin (@array) { if (($bin >= $1) && ($bin <= $2)) { print "$1 $2\n"; last; } } }
      Thanks for suggesting a good approach :-)
Re: Problem in Foreach loop
by toolic (Bishop) on Apr 02, 2009 at 02:23 UTC
    2 hints:

    Check the contents of your @array. I suspect it does not contain what you think it should:

    use Data::Dumper; print Dumper(\@array);

    You never print out the lines of your input file which match your conditions. I expect to see print $_; somewhere inside your while loop. The name of your $line variable is confusing to me. I would have expected it to be a line of your input file, but it is an element of your poorly-named @array.

      I checked the array content with data dumper. Its correct
      Well as for $_ I am already using $1 and $2 match variables as per my if condition for $_
        Apologies if I am being particularly dense here but I still don't quite see what you are trying to achieve. When you say "I want to find breaks in 100's and then print those record names at the break points" what exactly do you mean and which fields (and which parts of those fields if applicable) are you trying to break on?
Re: Problem in Foreach loop
by Ish (Acolyte) on Apr 02, 2009 at 02:13 UTC
    Hi, could you please explain what it is you actually want to achieve? Thanks.
      I have a data suppose 1000 records I want to find breaks in 100's and then print those record names at the break points. As simple as that.
Re: Problem in Foreach loop
by Ish (Acolyte) on Apr 02, 2009 at 03:42 UTC
    OK, let me check if I have this right. You want to have the input numbers from the line where they straddle the values you produce in $bin?
      Yes.. exactly :-) thanks.