What is the best way to ascertain the length (in characters) of the longest element in an array?
What is the best way to ascertain the length (in characters) of the longest element in an array?
I need to find the longest element in an array of option values for a select box so that I can set the width dynamically.
Answers
This returns the key of the longest value and can also give you the value itself
function array_longest_value( $array, &$val = null ) { $val = null; $result = null; foreach( array_keys( $array ) as $i ) { $l = strlen( $array[ $i ] ); if ( $l > $result ) { $result = $i; $val = $array[ $i ]; } } return $result; }
If you just want the highest value:
echo max(array_map('strlen', $arr));
If you want the longest values:
function array_longest_strings(array $arr) { $arr2 = array_map('strlen', $arr); $arr3 = array_intersect($arr2, array(max($arr2))); return array_intersect_key($arr, $arr3); } print_r(array_longest_strings($arr));
I thought I'd write this in a different, and less obvious way, for the hell of it.
No conditionals, understanding how this works, is an exercise left to the reader.
$x = array( 'foo ', 'bar ____' , 'baz', 'q-----------', 'doo' ); function max_str( $stringArray ) { $m = '_'; foreach($stringArray as $item ) { $m[ strlen($item) ] = '_'; } return strlen( $m ); } print max_str( $x );
Note: Setting $m to be merely "" doesn't work. Php sucks, and for some reason casts $m into an array. Pure Genius.
Comment Responses
What's the point of not initializing $m=0 and then in the loop do $m = max($m, strlen($item))
Because I wanted to be different. That scope of answer had been provided. The Idea here was to try and "visually" processing it, in logical sense, I was trying to get as close as possible to the "print it into a dynamic text box and see how wide the text box is" logic. The only problem here is strings are not 2 dimensional, so vertically stacking the "lines" was as close as I could get. What I really wanted to do is something like
substr( $m , 0 , strlen($item)) = $item;
But php doesn't have LValues, and It would have been complicated and used awful loops to implement that, so I just short-circuited a little with '_' at $length position.
Sure, you may argue this is the wrong approach to the problem, but IMO, what is being attempted and the idea of solving it in PHP is also the wrong approach to the problem, so If I'm going to do something wrong, I may as well be innovatively wrong in ways that possibly expose other weird coding tricks.
Also, as far as I can see your function will be wrong for $stringArray = array("")..
Yes, A minor caveat I must admit, however, if the user has an option box with no strings or all strings being of 0 length, you have a big fail to start with, nobodys going to rightly give a toss that the option box is too large by 5 pixels in this case.
Why its all made of Fail
Realistically, Any algorithm which doesn't have a fully fledged character kerning map correlating pairs of characters to the effective space consumed will be incorrect. You're fine in a monospaced font, but anything else will be hillarious.
- iiiiiiiiii
- llllllllll
- oooooooooo
- mmmmmmmmmm
- iiiiiiiiii
- llllllllll
- oooooooooo
- mmmmmmmmmm
- iiiiiiiiii
- llllllllll
- oooooooooo
- mmmmmmmmmm
10 copies of each, but such space utilization variety!
$longval = 0; $index = -1; for($i = 0; $i < count($array); $i++) { if($len = strlen($array[$i]) > $longval) { $longval = $len; $index = $i; } }
Then you know $array[$index] has the longest element of length $longval
There are two ways of doing that :
- Iterate over the whole array and keep the maximum element size ;
- Not iterate over the whole array and get the maximum element size from a magic hat :-)
Then, you'll have to know what font you'll be using to display things, and get the caracter sizes, the kernings, and all that things, so that you'll be able to compute the real width of the words which, unless you're using a fixed width font, is not the number of caracters in the string you'll be displaying.