This function returns the middle of a array sorted array
sub Return_Middle { my @list = @_; return @list if ( scalar(@list) == 2 or scalar(@list) == 1 ); my @sorted = sort { $a <=> $b || $a cmp $b } @list; my @middle = drill_down(@sorted); return @middle; sub drill_down { my @list = @_; return @list if ( scalar(@list) == 2 ); return @list if ( scalar(@list) == 1 ); splice @list, -1, 1; splice @list, 0, 1; drill_down(@list); } }
UPDATE - here is the updated code that I used along with some other subs
my $SORTED = \&Do_Sort; sub Return_First { return $SORTED->(@_)->[0]; } sub Return_Last { return $SORTED->(@_)->[$#{ $SORTED }]; } sub Return_Middle { return $SORTED->(@_) if @_ < 3; splice @_, -1, 1; splice @_, 0, 1; Return_Middle(@_); } sub Do_Sort { sort { $a <=> $b || $a cmp $b } @_; }

Replies are listed 'Best First'.
Re: function that returns the middle of an array
by blazar (Canon) on Jan 10, 2006 at 14:26 UTC

    How 'bout

    sub drill_down { my $i=@_/2; @_[ @_%2 ? $i : ($i-1, $i) ]; }

    instead?

    Also, in various order:

    • No need for those scalars as == will impose scalar context anyway; to be sure
      return @_ if @_ < 3;
      would have sufficed in both cases;
    • you may just do:
      drill_down(@sorted); # as the last statement in your sub
      instead of
      my @middle = drill_down(@sorted); return @middle;
    • while it is perfectly legal to define the drill_down sub inside the Return_Middle one, they will be "global" anyway, and to do so would have some sense only if the former were a closure around some variable(s) lexically scoped to the latter, which is not the case.
Re: function that returns the middle of an array
by Roy Johnson (Monsignor) on Jan 10, 2006 at 15:57 UTC
    How about this? You find the middle of the array, which will either be an integer or a half-value. Return the slice indexed from the integer portion of the midpoint through the integer portion of the midpoint + .5. If the midpoint is a half-value, those will be different (so you return the two values that straddle the middle); otherwise, they will be the same, and you return just one value.
    sub Return_Middle { my $midpt = ($#_/2); @_[int($midpt) .. int($midpt + .5)]; }
    Update:
    The text description in the OP suggests that the array is already sorted, so I didn't see the point of sorting it again. But my code could be a drop-in for drilldown instead of Return_Middle, or a sort step could be added to it:
    sub Return_Middle { my $midpt = ($#_/2); (sort {$a <=> $b or $a cmp $b} @_)[int($midpt) .. int($midpt + .5)]; }

    Caution: Contents may have been coded under pressure.

      I think that your subroutine doesn't sort the array so it just returns the elements at the middle, not the median of the array.

Re: function that returns the middle of an array
by ambrus (Abbot) on Jan 10, 2006 at 17:36 UTC