从数组中选择第 n 个项目

2022-08-30 23:11:35

从大型数组中选择第 n 个项目的最有效方法是什么?有没有一种“聪明”的方式来做到这一点,或者循环是唯一的方法?

需要考虑的几点:

  • 数组非常大,有 130 000 个项目
  • 我必须选择每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++;
}

或者与模相同:

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

这些方法可能相当慢,有什么办法可以改进吗?还是我只是在这里劈头发?

编辑

有适当的解释,到处都是好的答案,试图选择最合适的答案作为公认的答案。谢谢!


答案 1

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的优化程度。它的表现可能非常糟糕。


答案 2

尝试 ArrayIterator::seek()

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