in reply to Re: For- loop increment not passing to inner block
in thread For- loop increment not passing to inner block

Ah! Of course! I wasn't resetting the filehandle! (Must. . . have. . . coffee. . ) The filehandle SORTD refers a textfile like this:
0912203749 0725284648 0608294149 0622424347 1219303436 1729313449 1015162331 . . .
These are actually groupings of five 2-digit numbers. My goal was to traverse it by column, using i*2 as a starting index (that part, at least, works fine). I probably should have explained that at the outset but, silly me, I thought the issue was probably too simple to require further elaboration (I won't make that mistake again). Bountiful thanks, CountZero!

Replies are listed 'Best First'.
Re^3: For- loop increment not passing to inner block
by graff (Chancellor) on Mar 30, 2008 at 21:51 UTC
    I might not understand the overall task, but I would be inclined to invert the order of your two loops: the "while" loop over the file data should be the outer loop, and the "for" loop over columns in each line should be the inner loop.

    If the file in question is not very big (e.g. less than, say, 50 MB on typical desktop machines of the last few years), and you have some reason to prefer your current ordering of the loops, it would be better to read the whole file content into a memory-resident array first, then use a nested "for" loop over that array, rather than repeating your "while" loop over the file contents.

    The point is that file i/o is quite slow relative to memory-internal operations, so reading data from a file just once (rather than five times) just makes more sense.

Re^3: For- loop increment not passing to inner block
by GrandFather (Saint) on Mar 30, 2008 at 22:01 UTC

    This is bread and butter stuff for Perl and there are many better ways to achieve what you are after. Some are likely to be outside your current comfort zone so sift through the following and see what you like the look of:

    use warnings; use strict; while (<DATA>) { chomp; my @numbers = unpack ("(a2)*", $_); print "unpacked: @numbers, "; @numbers = /(..)/g; print "matched: @numbers, "; @numbers = (); push @numbers, substr $_, 0, 2, '' while length $_; print "substr'd: @numbers\n"; } __DATA__ 0912203749 0725284648 0608294149 0622424347 1219303436 1729313449 1015162331

    Prints:

    unpacked: 09 12 20 37 49, matched: 09 12 20 37 49, substr'd: 09 12 20 +37 49 unpacked: 07 25 28 46 48, matched: 07 25 28 46 48, substr'd: 07 25 28 +46 48 unpacked: 06 08 29 41 49, matched: 06 08 29 41 49, substr'd: 06 08 29 +41 49 unpacked: 06 22 42 43 47, matched: 06 22 42 43 47, substr'd: 06 22 42 +43 47 unpacked: 12 19 30 34 36, matched: 12 19 30 34 36, substr'd: 12 19 30 +34 36 unpacked: 17 29 31 34 49, matched: 17 29 31 34 49, substr'd: 17 29 31 +34 49 unpacked: 10 15 16 23 31, matched: 10 15 16 23 31, substr'd: 10 15 16 +23 31

    Perl is environmentally friendly - it saves trees
      I got sidetracked, but finally got back to this and took a look at your ideas, Grandfather. I'm a little disconcerted that your examples are simply reading each row into an array, in different ways. Thanks for the stylistic tips, but I'm not sure how that's relevant to what I'm trying to do (aggregate individual columns for analysis), but I guess I explained it badly. No matter. My stupid error was caught by Count Zero, and my awkward approach works fine for now. I may re-implement it using an array of references (my original idea), but I was aiming for a quick-and-dirty solution (not to worry: it's neither for work or a homework assignment!) :) . Thanks again.

        Sans any context whatsoever, solving the immediate problem of reading and slicing up the file data seemed most helpful.

        With the small amount of additional context you have added a fuller implementation would be:

        use warnings; use strict; my @lines; while (<DATA>) { chomp; push @lines, [unpack ("(a2)*", $_)]; } __DATA__ 0912203749 0725284648 0608294149 0622424347 1219303436 1729313449 1015162331

        which pushes arrays of numbers into an array of lines creating a two dimensional array that you can use in subsequent processing:

        for my $column (0 .. 4) { my @byColumn = map {$_->[$column]} @lines; print "@byColumn\n"; }

        prints:

        09 07 06 06 12 17 10 12 25 08 22 19 29 15 20 28 29 42 30 31 16 37 46 41 43 34 34 23 49 48 49 47 36 49 31

        Perl is environmentally friendly - it saves trees
Re^3: For- loop increment not passing to inner block
by Anonymous Monk on Mar 30, 2008 at 23:35 UTC
    Thanks for the tips all, particularly Grandfather. I can assure you that, to the extent I have a "comfort zone," it's simply habits and prejudices carrying over from other languages I've used. There may be more than one way to do it, but I have no interest in using a Stradavarius to pound nails. I'm always interested in a better way to do it, and if that requires learning new things, that's all the better. Thanks again!