arrays tripping me up

O

Obantec Support

Hi

i am reading data from a mysql source and i need to on certain lines when a
match occurs read the next few lines and output if not blank, then continue
the loop.

all lines have text except for the odd blank line.

i am using

$nic_nam="ShowMe";

foreach $i (@result)
{

if ($i=~ m/$nic_nam/) {

print "Found SHowMe<br>\n";

#now if this matches out put the next few lines while not blank from
@results
#max is only ever 7 lines.

}
}


hope i have explained enough.

Mark
 
J

J. Gleixner

Obantec said:
Hi

i am reading data from a mysql source and i need to on certain lines when a
match occurs read the next few lines and output if not blank, then continue
the loop.

all lines have text except for the odd blank line.

i am using

$nic_nam="ShowMe";

foreach $i (@result)
{

if ($i=~ m/$nic_nam/) {

print "Found SHowMe<br>\n";

#now if this matches out put the next few lines while not blank from
@results
#max is only ever 7 lines.

}
}


hope i have explained enough.

No. Provide data and an example that can be tested. Populate @result,
and show what you'd like for output, with the given the input.

Here's a guess...

my $nic_nam = 'ShowMe';

my $found;
my $max = 7;
my $current;
for my $val ( @results )
{
if ( $found )
{
if( $current >= $max )
{
$current = 0;
$found = 0;
}
else
{
print "$val\n" unless $val =~ /^$/;
$current++;
next;
}
}

if ( $val =~ /$nic_nam/ )
{
print "Found SHowMe<br>\n";
$found = 1;
next;
}
}
 
P

Paul Lalli

Obantec said:
i am reading data from a mysql source and i need to on certain lines when a
match occurs read the next few lines and output if not blank, then continue
the loop.

all lines have text except for the odd blank line.

i am using

$nic_nam="ShowMe";

So you're not using strict? Please go read the Posting Guidelines for
this group before posting again.
foreach $i (@result)

$i is generally a variable used for integer-type counters. Each
element of @result is a string. Choose better variables names.

{

if ($i=~ m/$nic_nam/) {

print "Found SHowMe<br>\n";

#now if this matches out put the next few lines while not blank from
@results
#max is only ever 7 lines.

This conflicts with your statement above. Above, you said "output the
next few lines *if* not blank". Here you're saying *while* not blank.
Which is it?
}
}

hope i have explained enough.

Not really, no. You haven't given us any sample input, desired output,
or actual output. More to the point, you haven't showed us what
attempts you've already made to solve this problem, or explained how
those attempts failed. Again, go read the Posting Guidelines for this
group.

As a hunch, I'd bet you want to use the "flip" operator, as documented
in
perldoc perlop

Paul Lalli
 
I

it_says_BALLS_on_your forehead

Obantec said:
Hi

i am reading data from a mysql source

this is not really relevant since you already have the data in an array
of strings.
and i need to on certain lines when a
match occurs read the next few lines and output if not blank, then continue
the loop.

can you be more precise? what is 'the next few lines'?
all lines have text except for the odd blank line.

i am using

$nic_nam="ShowMe";

foreach $i (@result)
{

if ($i=~ m/$nic_nam/) {

print "Found SHowMe<br>\n";

#now if this matches out put the next few lines while not blank from
@results
#max is only ever 7 lines.

}
}


hope i have explained enough.

#!/usr/local/bin/perl

use strict;
use warnings;

my @results = qw( showme showme two three four five six seven eight
nine showme eleven );

for my $i ( 0 .. $#results ) {
do {
my $start = defined $results[$i+1] ? $i+1 : $#results;
my $end = defined $results[$i+2] ? $i+2 : $#results;
my @new = @results[$start..$end];
for my $elem ( @new ) {
print "$elem\n" unless $elem =~ m/^\s*$/;
};
} if $results[$i] =~ m/showme/;
}
 
M

Matt Garrish

Jim Gibson said:
Use a C-style for loop (untested):

for( my $i = 0; $i < @result; $i++ ) {

for my $i (0..$#result) {

This is a Perl group after all... : )

Matt
 
I

it_says_BALLS_on_your_forehead

Jim said:
[problem processing array]
[snipped snippet un-snipped:]
for my $i (0..$#result) {
if( $result[$i] =~ /$nic_nam/ ) {
print "Match found: $result[$i];
while( $result[$i+1] != /^\s*$/ ) {
print $result[++$i];
}
}
}

This is a Perl group after all... : )


Matt:

Did you try it? Your suggestion doesn't work. The OP wanted to print
non-blank lines occuring in the array after any element matching a
regex was encountered.

I am afraid you have run afoul of the
knee-jerk-reaction-to-C-style-loops syndrome (or what some native
Choctaw speakers might describe as "cargo-cult programming" :^) that
occurs frequently in this group. Fortunately, the inventor of Perl saw
fit to include C-style loops in the language, perhaps for a good
reason.


Jim 45% cat matt.pl
#!/usr/local/bin/perl
use strict;
use warnings;

my @result = ( 1 .. 10 );
print "Matt's buggy loop:\n";
for my $i ( 0 .. $#result ) {
print "$result[$i]\n";
$i++ if( $i % 2 == 0 );
}

print "\nJim's correct loop:\n";
for( my $j = 0; $j < @result; $j++ ) {
print "$result[$j]\n";
$j++ if( $j % 2 == 0 );
}
Jim 46% perl matt.pl
Matt's buggy loop:
1
2
3
4
5
6
7
8
9
10

Jim's correct loop:
1
3
5
7
9
Jim 47%

Jim, the below code generated the same output as your C-style code...

use strict; use warnings;

my @result = ( 1 .. 10 );

for my $i ( 0 .. $#result ) {
if ( $i % 2 == 0 ) {
print "$result[$i]\n";
}
else {
$i++;
}
}

__OUTPUT__
1
3
5
7
9
 
I

it_says_BALLS_on_your_forehead

it_says_BALLS_on_your_forehead said:
Jim said:
Matt Garrish said:

[problem processing array]
Use a C-style for loop (untested):

for( my $i = 0; $i < @result; $i++ ) {
[snipped snippet un-snipped:]
for my $i (0..$#result) {
if( $result[$i] =~ /$nic_nam/ ) {
print "Match found: $result[$i];
while( $result[$i+1] != /^\s*$/ ) {
print $result[++$i];
}
}
}

This is a Perl group after all... : )


Matt:

Did you try it? Your suggestion doesn't work. The OP wanted to print
non-blank lines occuring in the array after any element matching a
regex was encountered.

I am afraid you have run afoul of the
knee-jerk-reaction-to-C-style-loops syndrome (or what some native
Choctaw speakers might describe as "cargo-cult programming" :^) that
occurs frequently in this group. Fortunately, the inventor of Perl saw
fit to include C-style loops in the language, perhaps for a good
reason.


Jim 45% cat matt.pl
#!/usr/local/bin/perl
use strict;
use warnings;

my @result = ( 1 .. 10 );
print "Matt's buggy loop:\n";
for my $i ( 0 .. $#result ) {
print "$result[$i]\n";
$i++ if( $i % 2 == 0 );
}

print "\nJim's correct loop:\n";
for( my $j = 0; $j < @result; $j++ ) {
print "$result[$j]\n";
$j++ if( $j % 2 == 0 );
}
Jim 46% perl matt.pl
Matt's buggy loop:
1
2
3
4
5
6
7
8
9
10

Jim's correct loop:
1
3
5
7
9
Jim 47%

Jim, the below code generated the same output as your C-style code...

use strict; use warnings;

my @result = ( 1 .. 10 );

for my $i ( 0 .. $#result ) {
if ( $i % 2 == 0 ) {
print "$result[$i]\n";
}
else {
$i++;
}
}

__OUTPUT__
1
3
5
7
9

hmm...actually, my output was the same as yours by coincidence.


for my $i ( 0 .. $#result ) {
print "before $i--";
if ( $i % 2 == 0 ) {
print "$result[$i]-";
}
else {
$i++;
}
print "--after $i\n";
}


for( my $j = 0; $j < @result; $j++ ) {
print "$j: $result[$j]\n";
$j++ if( $j % 2 == 0 );

}


__OUTPUT__
before 0--1---after 0
before 1----after 2
before 2--3---after 2
before 3----after 4
before 4--5---after 4
before 5----after 6
before 6--7---after 6
before 7----after 8
before 8--9---after 8
before 9----after 10
0: 1
2: 3
4: 5
6: 7
8: 9


....would you call this a bug? is it an issue of scope? i don't have
access to my Programming Perl book right now...will check it out when I
get to work tomorrow...
 
I

it_says_BALLS_on_your_forehead

Jim said:
Obantec Support said:
Hi

i am reading data from a mysql source and i need to on certain lines when a
match occurs read the next few lines and output if not blank, then continue
the loop.

all lines have text except for the odd blank line.

i am using

$nic_nam="ShowMe";

foreach $i (@result)
{

if ($i=~ m/$nic_nam/) {

print "Found SHowMe<br>\n";

#now if this matches out put the next few lines while not blank from
@results
#max is only ever 7 lines.

}
}

Use a C-style for loop (untested):

for( my $i = 0; $i < @result; $i++ ) {
if( $result[$i] =~ /$nic_nam/ ) {
print "Match found: $result[$i];
while( $result[$i+1] != /^\s*$/ ) {
print $result[++$i];
}
}
}

this fails to conform to the behavior specified by the OP on arrays
that contain strings matching the pattern in adjacent indices.

for instance:

my @data = qw( zero pattern1 pattern2 three four );

assuming that 'next few' is 2, the output based on the OP's description
should be (since there are no blanks):
# matches pattern1, so prints the following 2 lines...
pattern2
three

# continues loop, starting from where we left off before (OP a little
unclear here though)
# so now at pattern2, and matches again, so prints the next 2 lines...
three
four
 
R

robic0

Jim said:
Obantec Support said:
Hi

i am reading data from a mysql source and i need to on certain lines when a
match occurs read the next few lines and output if not blank, then continue
the loop.

all lines have text except for the odd blank line.

i am using

$nic_nam="ShowMe";

foreach $i (@result)
{

if ($i=~ m/$nic_nam/) {

print "Found SHowMe<br>\n";

#now if this matches out put the next few lines while not blank from
@results
#max is only ever 7 lines.

}
}

Use a C-style for loop (untested):

for( my $i = 0; $i < @result; $i++ ) {
if( $result[$i] =~ /$nic_nam/ ) {
print "Match found: $result[$i];
while( $result[$i+1] != /^\s*$/ ) {
print $result[++$i];
}
}
}

this fails to conform to the behavior specified by the OP on arrays
that contain strings matching the pattern in adjacent indices.

for instance:

my @data = qw( zero pattern1 pattern2 three four );

assuming that 'next few' is 2, the output based on the OP's description
should be (since there are no blanks):
# matches pattern1, so prints the following 2 lines...
pattern2
three

# continues loop, starting from where we left off before (OP a little
unclear here though)
# so now at pattern2, and matches again, so prints the next 2 lines...
three
four

There is no conformity on the OP's statements. The OP's statements have
conceptual errors. Why try to read into an errant proposition.
A test of a good programmer is to take in the whole proposition and make
an immediate analysis/assesment of the completeness of if or otherwise.
A single read of the statement and you realize its an incomplete thought.

Unless your bored and young, why try to make it into a federal case?
There's many years ahead that will bust your nut on big programming asignments
to get worked up with this.

Let it go. If its not obvious whats wrong then just ask.
 
I

it_says_BALLS_on_your_forehead

robic0 said:
Jim said:
Hi

i am reading data from a mysql source and i need to on certain lines when a
match occurs read the next few lines and output if not blank, then continue
the loop.

all lines have text except for the odd blank line.

i am using

$nic_nam="ShowMe";

foreach $i (@result)
{

if ($i=~ m/$nic_nam/) {

print "Found SHowMe<br>\n";

#now if this matches out put the next few lines while not blank from
@results
#max is only ever 7 lines.

}
}

Use a C-style for loop (untested):

for( my $i = 0; $i < @result; $i++ ) {
if( $result[$i] =~ /$nic_nam/ ) {
print "Match found: $result[$i];
while( $result[$i+1] != /^\s*$/ ) {
print $result[++$i];
}
}
}

this fails to conform to the behavior specified by the OP on arrays
that contain strings matching the pattern in adjacent indices.

for instance:

my @data = qw( zero pattern1 pattern2 three four );

assuming that 'next few' is 2, the output based on the OP's description
should be (since there are no blanks):
# matches pattern1, so prints the following 2 lines...
pattern2
three

# continues loop, starting from where we left off before (OP a little
unclear here though)
# so now at pattern2, and matches again, so prints the next 2 lines...
three
four

There is no conformity on the OP's statements. The OP's statements have
conceptual errors. Why try to read into an errant proposition.
A test of a good programmer is to take in the whole proposition and make
an immediate analysis/assesment of the completeness of if or otherwise.
A single read of the statement and you realize its an incomplete thought.

Unless your bored and young, why try to make it into a federal case?
There's many years ahead that will bust your nut on big programming asignments
to get worked up with this.

i'm not making anything into a federal case. i'm trying to be as
meticulous as possible because *not* being meticulous is precisely what
will "bust my nut" on big programming assignments.

if i make an error, i hope that someone will point it out so i won't
make it again, and so i can go back and fix code that is a timebomb
waiting to explode.
 
M

Matt Garrish

Jim Gibson said:
[problem processing array]
[snipped snippet un-snipped:]
for my $i (0..$#result) {
if( $result[$i] =~ /$nic_nam/ ) {
print "Match found: $result[$i];
while( $result[$i+1] != /^\s*$/ ) {
print $result[++$i];
}
}
}

This is a Perl group after all... : )


Did you try it? Your suggestion doesn't work. The OP wanted to print
non-blank lines occuring in the array after any element matching a
regex was encountered.

You caught me. I get so tired of seeing needless c-style loops that I missed
the ++$i. My bad... (and no, I don't test other people's untested code!)

Matt
 
J

John W. Krahn

it_says_BALLS_on_your_forehead said:
Jim, the below code generated the same output as your C-style code...

use strict; use warnings;

my @result = ( 1 .. 10 );

for my $i ( 0 .. $#result ) {
if ( $i % 2 == 0 ) {
print "$result[$i]\n";
}
else {
$i++;
}

The else block is superfluous as the value of $i is set from the list ( 0 ..
$#result ).
}

__OUTPUT__
1
3
5
7
9


John
 
I

it_says_BALLS_on_your forehead

John said:
it_says_BALLS_on_your_forehead said:
Jim, the below code generated the same output as your C-style code...

use strict; use warnings;

my @result = ( 1 .. 10 );

for my $i ( 0 .. $#result ) {
if ( $i % 2 == 0 ) {
print "$result[$i]\n";
}
else {
$i++;
}
}
The else block is superfluous as the value of $i is set from the list ( 0 ..
$#result ).

interesting. so in old C-style for loops, the value of $i can be
changed within the loop, but it cannot in the above code.
 
P

Paul Lalli

it_says_BALLS_on_your forehead said:
John said:
it_says_BALLS_on_your_forehead said:
Jim, the below code generated the same output as your C-style code...

use strict; use warnings;

my @result = ( 1 .. 10 );

for my $i ( 0 .. $#result ) {
if ( $i % 2 == 0 ) {
print "$result[$i]\n";
}
else {
$i++;
}
}
The else block is superfluous as the value of $i is set from the list ( 0 ..
$#result ).

interesting. so in old C-style for loops, the value of $i can be
changed within the loop, but it cannot in the above code.

That's because a for loop and a foreach loop are not the same thing. A
foreach loop sets the loop variable to each element of the list, in
turn. Changing the value of that loop variable does not cause the loop
to "skip" any elements.

In fact, I'm somewhat surprised trying to do $i++ there does not result
in "modification of read-only attempted" or similar, as $i should be an
alias to each of the constants from 0 to $#result.

Paul Lalli
 
I

it_says_BALLS_on_your forehead

Paul said:
it_says_BALLS_on_your forehead said:
John said:
it_says_BALLS_on_your_forehead wrote:

Jim, the below code generated the same output as your C-style code...

use strict; use warnings;

my @result = ( 1 .. 10 );

for my $i ( 0 .. $#result ) {
if ( $i % 2 == 0 ) {
print "$result[$i]\n";
}
else {
$i++;
}
}
The else block is superfluous as the value of $i is set from the list ( 0 ..
$#result ).

interesting. so in old C-style for loops, the value of $i can be
changed within the loop, but it cannot in the above code.

That's because a for loop and a foreach loop are not the same thing. A
foreach loop sets the loop variable to each element of the list, in
turn. Changing the value of that loop variable does not cause the loop
to "skip" any elements.

In fact, I'm somewhat surprised trying to do $i++ there does not result
in "modification of read-only attempted" or similar, as $i should be an
alias to each of the constants from 0 to $#result.


what you say makes sense, however, *i'm* somewhat surprised since
Programming Perl 3rd ed. p. 118 states:
The foreach keyword is just a synonym for the for keyword, so you
can use for and foreach interchangeably, whichever you think is more
readable in a given situation.

i think that the context in which the 'for' control word is used is the
distinguishing factor. if the argument is a list, Perl treats it as an
alias for foreach, if the argument contains semicolons, then Perl
treats it like a C for loop.
 
P

Paul Lalli

it_says_BALLS_on_your forehead said:
what you say makes sense, however, *i'm* somewhat surprised since
Programming Perl 3rd ed. p. 118 states:
The foreach keyword is just a synonym for the for keyword, so you
can use for and foreach interchangeably, whichever you think is more
readable in a given situation.

i think that the context in which the 'for' control word is used is the
distinguishing factor. if the argument is a list, Perl treats it as an
alias for foreach, if the argument contains semicolons, then Perl
treats it like a C for loop.

You are absolutely correct. Perl uses the context of what follows
for/foreach to determine what kind of loop to use. However, once that
decision has been made, the two kinds of loops are completely distinct.

Paul Lalli
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top