Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: The error says the value is uninitialized, but it works anyway

by holli (Monsignor)
on Aug 18, 2019 at 11:32 UTC ( #11104652=note: print w/replies, xml ) Need Help??


in reply to The error says the value is uninitialized, but it works anyway

As a general rule, you should avoid changing an array you are iterating over. That's bound to cause all kinds of headaches. Also, it is favourable to name variables by what they mean, not by what they contain. Here, $num is a bad name. $index is better, so are $i, $j, $k, etc.

Here's my stab at the problem.
use strict; use warnings; my @colors = qw(red green blue yellow pink purple brown); my @drop = qw(pink brown); foreach my $drop_color (@drop) { my $index = 0; foreach my $color (@colors) { if ( $color eq $drop_color ) { splice (@colors, $index, 1); last; } $index++; } } print "@colors \n";
Besides being clearer, this also works with n elements in whatever array, whereas your solution hardcodes two elements in the @drop.


holli

You can lead your users to water, but alas, you cannot drown them.

Replies are listed 'Best First'.
Re^2: The error says the value is uninitialized, but it works anyway
by jcb (Chaplain) on Aug 19, 2019 at 00:42 UTC

    It is probably worth noting here that $i, $j, $k, $l, and so on are only good loop iteration variables because of the sheer weight of the long-standing convention of using them that way.

    As far as I know, this convention originated with the C programming language, although the fact that I, J, K and some others default as integers in FORTRAN suggests that it is older than C. These variables are probably best used when your iteration variables will have integer values, as that is also a (weaker) long-standing convention. In the example that started this discussion, the iteration was over the positions in an array, which are integers in Perl. If you are iterating over the values of an array, as in the solution presented by holli above, you should use a descriptive iterator variable as holli did.

    The solution holli presented also illustrates another problem: algorithmic complexity. Nested loops are usually the slowest practical way to solve a problem, and when you see such a construction, you should consider if there is a better way, and explicitly checking two elements of @drop is really just an unrolled nested loop. (See also: Loop unrolling) On modern hardware, the issue will be unnoticeable until you are trying to process large amounts of data, and then your program will suddenly be horrendously slow. For more enlightenment on this, analyze the expected running time of the various solutions here and then run actual benchmarks with both the small data set given in the original assignment and some (much) larger generated data sets, with hundreds, thousands, tens of thousands, hundreds of thousands, and millions of items.

      I think usage of i, j, k for indexes is older, FORmulaTRANslator is oriented towards mathematical notation.

      However, in homework tasks for beginners, loop unrolling is less likely in the curriculum, and my guess is that it's all about that bass nested loops. All the other solutions given so far won't work if @drop has more or less that two elements…

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (9)
As of 2019-11-14 19:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Strict and warnings: which comes first?



    Results (80 votes). Check out past polls.

    Notices?