Re: Finding the Shortest Element in an Array
by blokhead (Monsignor) on Oct 13, 2005 at 19:43 UTC
|
my @things = qw[ hello superduper hi ];
my $shortest = argmin { length } @things;
In English, this reads: "return the element among @things that minimizes the length function."
Alternatively, you could loop through the array, manually keeping a watermark of the shortest string seen so far and its index.
| [reply] [d/l] |
Re: Finding the Shortest Element in an Array
by friedo (Prior) on Oct 13, 2005 at 19:42 UTC
|
Here's the long drawn-out way, but I'm sure some people will be along shortly with more elegant solutions:
my @array = qw(hello superduper hi);
my $shortest = $array[0];
for( @array ) {
$shortest = $_ if length $_ < length $shortest;
}
| [reply] [d/l] |
Re: Finding the Shortest Element in an Array
by borisz (Canon) on Oct 13, 2005 at 20:39 UTC
|
use List::Util qw/reduce/;
@array = qw( hello superduper hi );
print reduce { length( $a ) < length( $b ) ? $a : $b } @array;
| [reply] [d/l] |
Re: Finding the Shortest Element in an Array
by holli (Abbot) on Oct 13, 2005 at 19:57 UTC
|
my @a = qw(4444 22 1 22 333);
my $shortest;
my $min;
for ( @a )
{
my $l = length($_);
if (not defined $min or $l<$min )
{
$min=$l;
$shortest=$_;
}
}
print $shortest;
Edit: looks like i was way to slow again.
| [reply] [d/l] |
Re: Finding the Shortest Element in an Array
by haoess (Curate) on Oct 13, 2005 at 20:07 UTC
|
@array = qw( hello, superduper, hi )
Maybe it's a mistake, but this creates a list containing three comma ending strings.
For your algorithm you should have a look at the implementation of minmax in List::MoreUtils. It should be simple to adjust it to check for the length of a string. The documentation says:
The minmax algorithm differs from a naive iteration over the list where each element
is compared to two values being the so far calculated min and max value in that it
only requires 3n/2 - 2 comparisons. Thus it is the most efficient possible algorithm.
--Frank
| [reply] [d/l] [select] |
|
|
haoess,
Actually, using List::Util's 'reduce' would be better. The minmax algorithm is doing more work then it needs because it is trying to identify both the min and the max where here only the min is desired. So in addition to List::Util being part of the core, it is also XS in most environments and implements the watermark algorithm which for this is much more efficient than 'minmax';
| [reply] |
Re: Finding the Shortest Element in an Array
by Skeeve (Parson) on Oct 13, 2005 at 19:51 UTC
|
I would simply loop over the elements comparing each stringlength with the current minimal length.
While using all the bells and whistles with map and shift and sort and such, I think it's pretty overdone. Just as plain as this untested:
use strict;
use warnings;
my @array = qw( hello, superduper, hi );
# You know that those commas are part of the strings!?
my $shortest= $array[0];
my $shortest_length= length $shortest;
for ($i= $#array; $i; --$i) {
my $length= length $array[$i];
if ($length < $shortest_length) {
$shortest_length= $length;
$shortest= $array[$i];
}
}
print $shortest,"\n";
Of course, one can shorten this, but you wanted a direction, not a "nice" solution...
s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
+.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
| [reply] [d/l] [select] |
Re: Finding the Shortest Element in an Array
by injunjoel (Priest) on Oct 13, 2005 at 19:40 UTC
|
#!/usr/bin/perl -w
use strict;
my @array = qw(hello superduper hi);
#our good friend the ST (aka: Schwartzian Transform)
my $shortest = shift @{[
map{$_->[1]}
sort{$a->[0] <=> $b->[0]}
map{[length $_, $_]}@array
]};
print $shortest;
Hope that helps. Here is the documentation on what is going on with the Schwartzian Transform.
-InjunJoel
"I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo
| [reply] [d/l] |
|
|
injunjoel,
I am not sure why you suggested sorting a list to find the shortest element. A watermark algorithm should be used since sorting does far more work then is necessary. I would have suggested List::Util's 'reduce' function or a hand rolled one as I demonstrated in my How A Function Becomes Higher Order tutorial.
| [reply] |
|
|
Perhaps sort was chosen because using sort is easy on the person writing the code. That was the first thing that came to my mind -- just sort the list based on length, but i see no reason to use a Schwartzian Transform here. This should suffice, and while it may take longer and use more memory, it sure looks neat:
@array = sort { length($a) <=> length($b) } @array;
Code like that reminds me of my days painting dorm rooms. My boss would tell me "Let the brush do the work, not you." And yes, that would include using List::Util, FWIW.
| [reply] [d/l] |
|
|
|
|
|
|
|
| [reply] |
Re: Finding the Shortest Element in an Array
by murugu (Curate) on Oct 14, 2005 at 03:01 UTC
|
@a=qw(adddddd bcdef deed superlative);
($shortest)=sort{length($a)<=>length($b)}@a;
print $shortest;
Regards, Murugesan Kandasamy.
| [reply] [d/l] |
Re: Finding the Shortest Element in an Array
by tphyahoo (Vicar) on Oct 14, 2005 at 10:54 UTC
|
Well folks, here's a one-liner.
print my $shortest = ( sort { length($a) <=> length($b) } qw( hello su
+perduper hi ) )[0];
outputs: hi.
:) | [reply] [d/l] |
Re: Finding the Shortest Element in an Array
by MidLifeXis (Monsignor) on Oct 14, 2005 at 17:24 UTC
|
sub shortest {
my $shortest = length $_[0];
(grep {
$shortest = length
if($shortest > length);
$shortest == length;
}@_)[-1]);
}
| [reply] [d/l] |
Re: Finding the Shortest Element in an Array
by niraj_sheth (Initiate) on Oct 15, 2005 at 16:51 UTC
|
How about ..
my $first = (sort {length($a) <=> length($b)} @array)[0]; | [reply] |