PHP数组中最短/最长字符串长度

40

我有一个像这样的数组

$data = array(
    "163",
    "630",
    "43",
    "924",
    "4",
    "54"
);

我该如何根据字符串长度而非数值大小从中选择最小和最大值(在此示例中为1(最小)和3(最大))


2
你只需要字符串长度还是也需要字符串本身? - NullUserException
你应该使用字符串而不是这些数字,以消除长度/值混淆。 - Muhammad bin Yusrat
6个回答

65

看起来你应该使用一个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);

请注意,$lengths 数组是未排序的,因此您可以轻松地检索每个字符串长度的相应数字。


3
不错,你可以使用 array_map('strlen', $data) 来实现同样的效果。 - NullUserException
这绝对是最干净的解决方案,但效率不是很高,因为它需要遍历数组三次(array_map、min和max),所以如果你有巨大的数组,最好使用单个循环。 - Vinko Vrsalovic
@Vinko - 是的,我猜这就是NullUserException的答案会占优势的地方(在处理大型数组的情况下...或者在许多数组上非常频繁地使用此函数的情况下)。 - Peter Ajtai
小心 strlen - 它是以字节为单位的字符串长度,而不是字符数。在特殊(多字节)字符的情况下,字符数更大,因此必须使用 mb_strlen - mikep

5

这是 brian_d的代码 的改进版本:

$min = PHP_INT_MAX;
$max = -1;

foreach ($data as $a) {
    $length = strlen($a);
    $max = max($max, $length);
    $min = min($min, $length);
}

这似乎过于复杂(加上初始化的 $min$max),除非你正在处理一个巨大的数组,而你只想遍历一次。 - Peter Ajtai
哎呀,每次迭代都要调用三个函数?我可不会这么做。 - mickmackusa

4

虽然在这种情况下不建议这样做,因为你将遍历数组两次,但你也可以使用array_reduce来将每个元素与其余元素进行比较。就像这样:

<?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;
}
?>

如果您使用的是 PHP 5.3.0 及以上版本,您可以利用 闭包
<?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";
?>

2
$min = 100;
$max = -1;

foreach($data as $a){
  $length = strlen($a);
  if($length > $max){ $max = $length; }
  else if($length < $min){ $min = $length; }
}

它完全符合操作者的需求。 - Femaref
没错。$min 必须从一个非常大的数字开始(例如 int32.maxvalue?) - Femaref
或者你可以将$max$/$min$设置为第一个元素,然后在迭代中跳过它(可使用for循环更容易实现)。 - Matthew
@konforce:采用这种方法,您必须确保访问的是有效条目(考虑只有0或1个元素的数组),并且将引入更多的检查。 - NullUserException
无论哪种方式,您都必须检查空数组。使用Brian的代码,在空数组上获得$min=100, $max = -1。因此,假设您现在有一个非空数组,则没有其他条件与for ($i = 1; $i < $len; ++$i)。实际上,您避免了第一次迭代时的if/else(因为它被跳过)。此外,foreach往往是PHP中最差的迭代方式。但这些都是小问题,我离题了... - Matthew

1
<?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);

-2

为了完整起见,这里有一个一行代码实现最大值和最小值:

$maximum = max(array_map('strlen', $array));
$minimum = min(array_map('strlen', $array));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接