http://www.perlmonks.org?node_id=1045922


in reply to How to work with Arrays of 83,000 values

So, note how your code is now misformatted and actually corrupted in a few spots? In the future, please wrap code in <code> tags. See How do I post a question effectively?.

Reformatted, your code looks like:

#!/usr/bin/perl use strict; use warnings; my @readingbooks = ("a b", "c d", "e f", "g h"); my @readingdate = (1991, 1992, 1993, 1994); my @catbooks = ("one", "two", "three", "client's", "five", "six", "sev +en", "eight", "a b"); my @catdate = (1980, 1981, 1982, 1994, 1984, 1985, 1986, 1987, 1991); my $rdbooks; my $rddate; my $cataloguebooks; my $cataloguedate; for (0..$#readingbooks){ $rdbooks = $readingbooks[$_]; $rddate = $readingdate[$_]; for (0..$#catbooks){ $cataloguebooks = $catbooks[$_]; $cataloguedate = $catdate[$_]; if (($rdbooks eq $cataloguebooks) && ($rddate == $cataloguedat +e)) { print "$rdbooks \t $cataloguebooks \n"; print "$rddate \t $cataloguedate \n"; print "wow \n\n"; } } }
A few critiques, since as MidLifeXis points out, you don't tell us how it doesn't work.
  1. You've scoped $rdbooks, $rddate, $cataloguebooks, and $cataloguedate outside your nested loops, despite the fact that you never use those values outside that scope. While this doesn't cause any trouble for you in this case, it's an easy way to accidentally have data leak outside scope and cause trouble.
  2. Part of the reason you have to stash the values in temporary variables is that you don't name your indices. If you swap to something that looks more like
    for my $i (0..$#readingbooks){ for my $j (0..$#catbooks){ if (($readingbooks[$i] eq $catbooks[$i])...
    it saves typing, reduces complexity, and makes intent more obvious.
  3. Almost any time you have nested for loops around an equality test in Perl, you should really be using hashes (or possibly a real database for very large cases). It'll be dramatically faster. Modifying your posted code:
    #!/usr/bin/perl use strict; use warnings; my @readingbooks = ("a b", "c d", "e f", "g h"); my @readingdate = (1991, 1992, 1993, 1994); my %readingbooks_hash; $readingbooks_hash{$_}++ for @readingbooks; my %readingdate_hash; $readingdate_hash{$_}++ for @readingdate; my @catbooks = ("one", "two", "three", "client's", "five", "six", "sev +en", "eight", "a b"); my @catdate = (1980, 1981, 1982, 1994, 1984, 1985, 1986, 1987, 1991); for my $i (0 .. $#catbooks) { if ($readingbooks_hash{$catbooks[$i]} and $readingdate_hash{$catda +te[$i]}) { print "$catbooks[$i]\t$catdate[$i]\n"; print "wow \n\n"; } }

There are a number of additional improvements, particularly swapping from coordinated arrays to arrays of hashrefs (perllol) or even formal objects (Moose), but this should dramatically improve your situation.


#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.