in reply to Re: Getting last valid index from a particular list in a @LoL
in thread Getting last valid index from a particular list in a @LoL

This node falls below the community's threshold of quality. You may see it by logging in.
  • Comment on Re: Re: Getting last valid index from a particular list in a @LoL

Replies are listed 'Best First'.
Re: Re: Re: Getting last valid index from a particular list in a @LoL
by blakem (Monsignor) on Oct 17, 2001 at 00:17 UTC
    #!/usr/bin/perl -wT use strict; my @aoa = ([1,2,3], [1,2,3,4,5], [1,2,3,4,5,6,7,8], [1,2,3,4], [1,2,3,4,5,6], ); my $i; my $index = (sort{$$b[1]-$$a[1]}map{[$i++,$#$_]}@aoa)[0]->[0]; print "\$aoa[$index] has the most elements\n"; =OUTPUT $aoa[2] has the most elements

    -Blake

      $index = (sort{$$b[1]-$$a[1]}map{[$i++,$#$_]}@aoa)[0]->[0];
      That's nice, very nice indeed, blakem ... but some people seem to have problems understanding it, so allow me to take this apart a bit:
      1. @tmp = map {[$i++,$#$_]} @aoa;This creates a list of two element arrays (yes, to be precise of references to two element arrays). The first being the position (index) in @aoa, the second the last index of the current array in @aoa. So for the example given, this produces the following array: ( [0,2], [1,4], [2,7], [3,3], [4,5] )
      2. @sorted = sort {$$b[1]-$$a[1]} @tmp;This created list is now sorted on the 2nd (last index) element, with the biggest element sorted to the head of the list. $$b[1]-$$a[1] is just a fancy way of writing $$b[1] <=> $$a[1] which might look more familiar. So the list now looks like this: ( [2,7], [4,5], [1,4], [3,3], [0,2] )
      3. $index = $sorted[0]->[0];As a last step, the first element of the sorted list is taken (i.e. [2,7] in our example, a reference to a 2 element array) and the first (->[0]) item is extracted. This is the index we were looking for.

      -- Hofmator

        Thanks for expounding on my uncharacteristically terse answer. I was a bit grumpy when I wrote it, having just gone a few rounds over at Varying Variable Names.....

        -Blake

Re: Re: Re: Getting last valid index from a particular list in a @LoL
by merlyn (Sage) on Oct 17, 2001 at 04:03 UTC
      That gives last index *in* the longest array, not the index *of* said array, which is what was asked for. In otherwords, he's trying to locate the longest array, not necessarily find out how long it is.

      Update: merlyn's new code address the issue, nicely....

      -Blake

      Aren't you tying your leg to your cheek there by going through the array twice? :-/

      It's irrelevant when the script is going to be thrown away two days later of course, but I'd never put any bets on that. "A little" sloppiness here and "a little" there and some more at another place tends to pile up faster than you notice..
        I'll bet you that for a 10-50 element list, my method to find all points which have a maximum beats any method where you do all the bookkeeping yourself. List::Util::max and grep are darn fast.

        -- Randal L. Schwartz, Perl hacker

Re^3: Getting last valid index from a particular list in a @LoL
by Aristotle (Chancellor) on Oct 17, 2001 at 07:33 UTC
    #!/usr/bin/perl -wT use strict; my @lol = ([1,2,3], [1,2,3,4,5], [1,2,3,4,5,6,7,8], [1,2,3,4], [1,2,3,4,5,6], ); my $index = 0; $index = $#{$lol[$index]} < $#{$lol[$_]} ? $_ : $index for 0 .. $# +lol; print "\$aoa[$index] has the most elements\n"; =OUTPUT $aoa[2] has the most elements
    And just for the fun of it, a bit faster if you have a couple hundred thousand lists in the list at the cost of extra clutter :-) :
    my ($index,$len) = (0,0); $index = $len < $#{$lol[$_]} ? do { $len = $#{$lol[$_]}; $_ } : $i +ndex for 0 .. $#lol;
    I'm still trying to figure out what blakem was thinking btw..
Re: Re: Re: Getting last valid index from a particular list in a @LoL
by thinker (Parson) on Oct 17, 2001 at 00:38 UTC
    Hi willick,

    Here's one way to do it. You will probably want to adjust it.

    Note that I have not allowed for two (longest) duplicate length lists.

    #!/usr/bin/perl -w use strict; my @lol=([4,5,6,17,42],[10,20,30],[6,7,8,36,55,44]); my ($row,$max,$i); $row=$max=$i=0; for(@lol) { for ($_){ if ($#$_>$max){ $max=$#$_;$row=$i} ; }; $i++ } printf ("Maximum Index is %i, located in row %i \n",$max,$row);


    cheers

    thinker