$element_count = $#Array;
Note that the variable name erroneously states that the variable contains a count of the elements.
Same as 1352.
Although not explicitly obfuscated, the code was very difficult to understand:
@seen{map { my $la = $_; map { $la->[$_ & ~1] } 2 .. $#$la; } $parser->links} = ();
$parser->links here returns a data structure of the form
([P, a,1,b,2,c,3], [Q, d,4,e,5], [R, f,6,g,7,a,8], [S, b,9,e,19,g,11]);
(Apparently it is the return from HTML::LinkExtor.) The goal here is to create a hash whose keys are 1, 2, 3, 4, etc. The values are unimportant.
The author says:
I wouldn't suggest using it, but you might have been considering it.
The code was
my $sortkeys = join " || ", map "\$a->{\$sortkeys[$_]} cmp \$b->{\$sortkeys[$_]}", 0..$#sortkeys;
Although it's tempting to suggest that it could be replaced with a simpler, $#array-less version:
my $sortkeys = join " || ", map "\$a->{$_} cmp \$b->{$_}", @sortkeys;
that would not be correct in this case. The author wanted to consider the situation where @sortkeys might contain elements with spaces or other punctuation characters, and the complicated version is required for this.
The poster is constructing a three-dimensional array and wants to replace an index loop with en element loop:
2) I use a[i][j][k] for getting/setting values, its 3 loops and is cumbersume. 3) I'd like to know how I can get/set values without using indexes. i.e for a simple array: instead of for ($i=0; $i <=$#ARR; $i++) I'd like to use for $val (@ARR) But in my case, $val will be a reference until I read the 3rd level, right?
The post is demonstrating an expression that prints out only elements 1, 3, 5, ... from an array. The demonstration is:
for (0..10) { my @array1 = (1..$_); print "$_: >@array1[map 1+2*$_, 0..($#array1-1)/2]<\n"; }
Note the rare use of $#array1-1. This is identical to @array1-2:
for (0..10) { my @array1 = (1..$_); print "$_: >@array1[map 1+2*$_, 0..(@array1-2)/2]<\n"; }
With this change, we can move the -2 out of the fraction:
for (0..10) { my @array1 = (1..$_); print "$_: >@array1[map 1+2*$_, 0.. @array1/2 -1 ]<\n"; }
This suggests the following transformation:
for (0..10) { my @array1 = (1..$_); print "$_: >@array1[map 2*$_-1, 1.. @array1/2 ]<\n"; }
The behavior is now a lot clearer. You can see at a glance how many elements will be printed out: Exactly half (rounded down). It is much more difficult to see this in the original code.
The author appears to believe that $#a=0 is necessary to initialize a previously unused Perl array to contain zero elements:
#!/usr/bin/perl open (IN,"data"); while (<IN>) { $#a=0; $serv=""; $i=""; push (@a,/\s(nam\S+)/g); for $i(@a) { ($serv)=/(^serv\S+\s+\S+)/; print "name = $i\n"; print "service = $serv\n"; } }In this case, the $#a=0; line is erroneous, since it is inserting an extra undefined item at the start of the array. The bug can be fixed by deleting the entire $#a=0; line.
The author has a list of records, each containing a domain name and a count:
@array = (['bath.ac.uk', '46'], ['blackpool.ac.uk', '22'], ... );
The user wants to eliminate duplicate domain names and sum the counts for each unique domain. The code presented sorts the array by domain name; then scans the array, comparing each element's domain with the next element's domain.
@array = sort { $a->[0] <=> $b->[0] } @array; $c = 0; for($r = 0;$r <= $#array;$r++) { if($array[$r][0] ne $array[$r+1][0]) { $domains[$c][0] = $array[$r][0]; $domains[$c][1] += $array[$r][1]; $c++; } else { $domains[$c][0] = $array[$r][0]; $domains[$c][1] += $array[$r][1]; } }
Note that the code, as presented, may have a bug, because it indexes off the end of the array.
Better code would be:
my (%seen, %count, @unique_domains); for (@array) { my ($domain, $count) = @$_; push @unique_domains, $domain unless $seen{$domain}++; $count{$domain} += $count; } @domains = map [$_, $count{$_}], @unique_domains;
If it's not necessary to preserve the original order of the array, then:
my (%count); for (@array) { my ($domain, $count) = @$_; $count{$domain} += $count; } @domains = map [$_, $count{$_}], keys %count;In either case, $#array is not required.
Return to: Universe of Discourse main page | Perl Paraphernalia | Classes and Talks Program Repair Shop and Red Flags | Survey of $#array Usage
mjd-perl-yak@plover.com