从数组中选择每个第n项

Tat*_*nen 14 php arrays

从大型数组中选择每个第n项的最有效方法是什么?是否有"聪明"的方式来实现或循环唯一的方式?

有些要考虑的要点:

  • 阵列非常大,有13万件物品
  • 我必须选择每个第205项
  • 这些项目没有数字索引,因此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++;
}
Run Code Online (Sandbox Code Playgroud)

或者与模数相同:

$result = array();
$i = 0;
foreach($source as $value) {
    if($i % 205 == 0) {
        $result[] = $value;
    }
    $i++;
}
Run Code Online (Sandbox Code Playgroud)

这些方法可能很慢,有什么办法可以改进吗?或者我只是在这里分裂头发?

编辑

通过正确的解释得到很好的答案,试图选择最合适的答案.谢谢!

Cor*_*lou 15

foreach循环基于比较测试为您的大型阵列提供最快的迭代.除非有人希望通过循环展开解决问题,否则我会坚持使用类似于你的东西.

这个答案应该更快.

$result = array();
$i = 0;
foreach($source as $value) {
    if ($i++ % 205 == 0) {
        $result[] = $value;
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有时间进行测试,但如果您首先对数组进行数字索引,则可以使用@ haim解决方案的变体.值得一试的是,您是否可以获得超过我之前的解决方案的任何收益:

$result = array();
$source = array_values($source);
$count = count($source);
for($i = 0; $i < $count; $i += 205) {
    $result[] = $source[$i];
}
Run Code Online (Sandbox Code Playgroud)

这在很大程度上取决于函数array_values的优化程度.它可能会表现得非常糟糕.


Gor*_*don 7

试试ArrayIterator :: seek()

此外,使用一个新的Spl数据结构可能比使用普通数组产生更好的结果.


Hai*_*vgi 6

我建议使用 array_slice

$count = count($array) ;
for($i=205;$i<$count;$i+=205){
    $result[] = array_slice($array,$i,1);
}
Run Code Online (Sandbox Code Playgroud)

如果你的数组被数字索引,这将是非常快的:

$count = count($array) ;
for($i=205;$i<$count;$i+=205){
    $result[] = $array[$i];
}
Run Code Online (Sandbox Code Playgroud)

  • @cballou,但请注意,此方法只需要执行130000/205循环,而foreach必须循环遍历所有130,000个项目.我必须测试它,我担心array_slice的性能,因为它可能在内部从0循环到$ i. (2认同)
  • 这在较大的阵列上确实很慢.如果将$ result = array_slice(...)更改为$ result [] = $ array [$ i],它比接受的解决方案更快. (2认同)