从大型数组中选择每个第n项的最高效方法是什么?是否有“聪明”的方式来做或者循环唯一的方式?
需要考虑的一些要点:
for($i = 0; $i <= 130000; $i += 205)
无效到目前为止,这是我提出的最有效的方法:
$result = array();
$i = 0;
foreach($source as $value) {
if($i >= 205) {
$i = 0;
}
if($i == 0) {
$result[] = $value;
}
$i++;
}
或与模数相同:
$result = array();
$i = 0;
foreach($source as $value) {
if($i % 205 == 0) {
$result[] = $value;
}
$i++;
}
这些方法可能很慢,有什么办法可以改进吗?或者我只是在这里分裂头发?
修改
通过正确的解释得到了很好的答案,试图选择最合适的答案。谢谢!
答案 0 :(得分:15)
foreach循环基于比较测试为您的大型阵列提供最快的迭代。除非有人希望通过循环展开解决问题,否则我会坚持使用类似于你的东西。
这个答案应该更快。
$result = array();
$i = 0;
foreach($source as $value) {
if ($i++ % 205 == 0) {
$result[] = $value;
}
}
我没有时间进行测试,但如果您首先对数组进行数字索引,则可以使用@ haim解决方案的变体。值得一试的是,您是否可以获得比我以前的解决方案更多的收益:
$result = array();
$source = array_values($source);
$count = count($source);
for($i = 0; $i < $count; $i += 205) {
$result[] = $source[$i];
}
这在很大程度上取决于函数array_values的优化程度。它可能会表现得非常糟糕。
答案 1 :(得分:7)
此外,使用新的Spl datastructures可能会产生比使用普通数组更好的结果。
答案 2 :(得分:6)
我建议使用array_slice
$count = count($array) ;
for($i=205;$i<$count;$i+=205){
$result[] = array_slice($array,$i,1);
}
如果您的数组以数字方式编入索引,则速度非常快:
$count = count($array) ;
for($i=205;$i<$count;$i+=205){
$result[] = $array[$i];
}
答案 3 :(得分:2)
我认为这个问题的解决方案不在于任何PHP语法,而在于代码的设计。
您可以对数组进行数字索引(对您的应用程序可能不合理),跟踪每个第205项,或只搜索一次数组(缓存每个第205项的列表)。
在我看来,跟踪每个第205项将更容易实现。您只需保留数据库中所有项目的计数,每次添加项目时,请检查计数的模数。如果您有另一个第205项,请将其添加到阵列。对于删除项目时,这将更加棘手。您可能需要重新检查整个阵列以重新排列所有第205个项目。
如果您可以从已删除的项目开始并向前移动,那么这样做会更简单,但这又适用于数字索引的数组 - 如果这是真的,那么您根本不需要前进,我会做一些小数学来重新计算出来。
答案 4 :(得分:1)
如果这确实是一个瓶颈,您可能需要考虑重新考虑您的设计,以便对其进行数字索引。
编辑:或者创建并维护一个单独的数组,只包含第205个项目(在插入时更新或类似的更新)。
答案 5 :(得分:0)
您似乎不能一次多次移动数组指针。我个人会用这个:
reset($source);
$next = true;
while($next === true){
$result[] = current($source);
for(i=0;i<205;i++){
$next = next($source);
}
}
如果某人能够找到一个可以一次移动数组指针的功能,那么你将获得更好的答案。我认为这很好。
答案 6 :(得分:0)
可能听起来很傻但是根据定义它是最快的,因为你直接访问内存位置而不进行任何比较。
答案 7 :(得分:-1)
您可以使用array_keys
仅对数组键起作用。
$keys = array_keys($array);
for ($i=0, $n=min(count($keys), 130000); $i<$n; $i += 205) {
$result[] = $array[$keys[$i]];
}