PHP shortest/longest string length in array
Solution 1
Seems like you should use an array_map()
// Convert array to an array of string lengths
$lengths = array_map('strlen', $data);
// Show min and max string length
echo "The shortest is " . min($lengths) .
". The longest is " . max($lengths);
Note that the $lengths
array is unsorted, so you can easily retrieve the corresponding number for each string length.
Solution 2
Here's an improved version of brian_d's code:
$min = PHP_INT_MAX;
$max = -1;
foreach ($data as $a) {
$length = strlen($a);
$max = max($max, $length);
$min = min($min, $length);
}
Solution 3
Although in this case it is not advisable because you'll be traversing the array twice, you can also use array_reduce to compare each element against the rest. Like this:
<?php
$data = array('163','630','43','42','999','31');
//Will return the longest element that is nearest to the end of the array (999)
//That's why we use strlen() on the result.
$max_l = strlen(array_reduce($data,'maxlen'));
//Will return the shortest element that is nearest to the end of the array (31)
$min_l = strlen(array_reduce($data,'minlen'));
echo "The longest word is $max_l characters, while the shortest is $min_l\n";
function maxlen($k,$v) {
if (strlen($k) > strlen($v)) return $k;
return $v;
}
function minlen($k,$v) {
if ($k == '') return PHP_INT_MAX;
if (strlen($k) < strlen($v)) return $k;
return $v;
}
?>
If you are using PHP 5.3.0+ you can take advantage of closures:
<?php
$max_l = strlen(array_reduce($data,
function ($k,$v) { return (strlen($k) > strlen($v)) ? $k : $v; }
));
$min_l = strlen(array_reduce($data,
function ($k,$v) {
if (!$k) return PHP_INT_MAX;
return (strlen($k) < strlen($v)) ? $k : $v;
}
));
echo "The longest word is $max_l characters, while the shortest is $min_l\n";
?>
Solution 4
$min = 100;
$max = -1;
foreach($data as $a){
$length = strlen($a);
if($length > $max){ $max = $length; }
else if($length < $min){ $min = $length; }
}
Solution 5
<?php
$array = array(
"163",
"630",
"43",
"924",
"4",
"54"
);
$arraycopy = array_map('strlen',$array);
asort($arraycopy);
$min = reset($arraycopy);
//if you need a single 'minword'
$minword = $array[key($arraycopy)];
//if you need them all
$minwords = array_intersect_key($array,array_flip(array_keys($arraycopy,$min)));
$max = end($arraycopy);
//if you need a single 'maxword'
$maxword = $array[key($arraycopy)];
//if you need them all:
$maxwords = array_intersect_key($array,array_flip(array_keys($arraycopy,$max)));
var_dump($min,$max,$minword,$maxword,$minwords,$maxwords);
Mark Lalor
I began my programming journey at the age of 11. My 5th grade teacher showed me that I could save a file on notepad with another file extension than .txt! Thus began my interest in HTML, CSS, Javascript, PHP, PHP GD, jQuery, SQL, C#, .NET Framework, C, C++, mobile apps, DragonFireSDK (7/10 would not use again), Objective C, and Java, in that order. I learned only through books and the internet, which is why I asked many dumb questions years ago. I like to look back on them and reminisce on my bad programming skills and problem-solving.
Updated on October 21, 2020Comments
-
Mark Lalor over 3 years
I have an array like this
$data = array( "163", "630", "43", "924", "4", "54" );
How can I select the smallest and largest values from it according to string length NOT number value. (for this example it is 1 (smallest) and 3 (largest).
-
Femaref over 13 yearsit does exactly what the op wants.
-
Femaref over 13 yearsthat's right though.
$min
has to start at a very high number (int32.maxvalue perhaps?) -
Matthew over 13 yearsOr you can set $max/$min to the first element and (optionally) skip it in the iteration. (Easier to do that with a
for
loop.) -
NullUserException over 13 years@konforce: With that approach you'd have to make sure you are accessing valid entries (think of arrays with 0 or 1 elements), and will introduce more checks.
-
Matthew over 13 yearsEither way you have to check for an empty array. With Brian's code, you get
$min=100, $max = -1
on an empty array. So assuming you now have a non-empty array, there is no additional condition withfor ($i = 1; $i < $len; ++$i)
. And in fact, you avoid the if/else on the first iteration (since it's skipped). Plus,foreach
tends to be the worst performing way to iterate in PHP. But these are minor points, and I digress... -
NullUserException over 13 years+1 Neat. You could just do
array_map('strlen', $data)
though; -
Vinko Vrsalovic over 13 yearsThis is by far the cleanest solution, but it's not very efficient, as it traverses the array three times (array_map, min and max), so if you have huge arrays, better use a single loop.
-
Peter Ajtai over 13 yearsThis seems overly complex (with the addition of an initialized
$min
and$max
), unless you are dealing with a huge array that you only want to traverse once. -
Peter Ajtai over 13 years@Vinko - Yeah, I guess that's where NullUserException's answer would gain the advantage (in the case of a huge array... or using this function very very many times on many many arrays).
-
mickmackusa about 4 yearsYeesh, three function calls on every iteration? I wouldn't.
-
mickmackusa about 4 yearsMapping the same array twice with strlen to produce the same outcome is the nonsensical way of executing the accepted answer (posted 9 years earlier). No new value in this post.
-
mikep over 3 yearsBe careful of
strlen
- it is string length in bytes not count of chars. Count of chars is bigger in case of special (multibyte) chars somb_strlen
must be used.