$list
是一个非常大的数组,包含一系列单词,其中一些大于5个字符,其中一些字符较小。此循环将取消设置字长超过5个字符的所有值。
for($i = 0; $i < count($list); $i++)
{
$list[$i] = trim($list[$i]);
if(strlen($list[$i]) > 5)
{
unset($list[$i]);
}
}
然而,这对于大约一半的$ list并且已经删除了死亡,这些单词比列表中剩下的5个字母长得多,但只是大约一半开始。是什么让它退出?我应该多次运行该循环吗?
答案 0 :(得分:7)
你每次都在呼唤计数,而你在循环中就是在取消东西。在循环之前只调用一次计数。无论如何这都是很好的做法,因为它大大减少了你必须进行的函数调用次数。
$count = count($list);
for($i = 0; $i < $count; $i++)
{
$list[$i] = trim($list[$i]);
if(strlen($list[$i]) > 5)
{
unset($list[$i]);
}
}
或者只是为了好玩,请使用array_map / array_filter:
$list = array_map('trim', $list);
$list = array_filter($list, function($s) { return strlen($s) <= 5; });
答案 1 :(得分:5)
它失败是因为你在缩小数组总长度的同时递增i
,这意味着在某些时候i
比当前数组长度更长。
更安全的做法是向后倒数:
for ( $i = count($list); $i--; )
{
$list[$i] = trim($list[$i]);
if(strlen($list[$i]) > 5)
{
unset($list[$i]);
}
}
答案 2 :(得分:2)
计数($ list)在取消设置$ list元素时发生变化,因此每次迭代计数都会返回一个较小的值。
答案 3 :(得分:1)
count()是问题所在。作为一个解决方案,我偏向于循环。
foreach ($list as $k => $v) {
$list[$k] = trim($v);
if (strlen($list[$k]) < 5) {
unset($list[$k]);
}
}
我认为它们比array_函数提供更好的清晰度。
答案 4 :(得分:0)
你需要从count($ list)循环到0;当你从头开始删除时,到实际结束时你实际上有更少的项目。
在循环之前存储count($ list)而不是每次都进行评估也很有用。
答案 5 :(得分:0)
当您unset()
元素时,count()
会减少。这意味着您所描述的内容很可能会发生。你最好在循环之前调用count()
一次,将它存储在一个变量中,然后在循环的顶部进行评估。
答案 6 :(得分:0)
在我的上网本糟糕的硬件上工作得非常快,有来自www.lipsum.com的10000个单词列表
function max_len_filter($var) {
if(strlen($var) > 5) return false;
return true;
}
$words = array_filter($words, 'max_len_filter');
var_dump($words);
希望它适合你
答案 7 :(得分:0)
每次调用unset()时,数组的长度都会发生变化。 只需将它存储在循环之前的变量中:
$count = count($list);
for($i = 0; $i < $count; $i++)
{
// your code
}