如何在 foreach 循环中跳过元素

28

我希望在 foreach 循环中跳过一些记录。

例如,循环中有 68 条记录。如何跳过前 20 条记录,从第 21 条记录开始?


2
你能展示一下你的代码吗?为什么特别使用 foreach 循环,如果它实际上并不是“for each”? - sarnold
5
有多种方法可以实现这个目标,但是你没有展示任何代码。根据你提到的记录,通常最好的做法是通过使用 LIMIT 修改 SQL 查询语句。 - hakre
这里可能需要使用 for 循环。然后,您可以在 for ($i = 20 ... ) 部分设置起始点。 - summea
7个回答

45

有五种解决方案:

使用array_keys进行双重寻址

使用for循环的问题在于键可能是字符串或不连续的数字,因此必须使用“双重寻址”(或“表查找”,随便你怎么称呼),通过其键的数组访问该数组。

// Initialize 25 items
$array = range( 1, 25, 1);

// You need to get array keys because it may be associative array
// Or it it will contain keys 0,1,2,5,6...
// If you have indexes staring from zero and continuous (eg. from db->fetch_all)
// you can just omit this
$keys = array_keys($array);
for( $i = 21; $i < 25; $i++){
    echo $array[ $keys[ $i]] . "\n";
    // echo $array[$i] . "\n"; // with continuous numeric keys
}

使用foreach跳过记录

我认为这不是一个好的做法(除非你有大型数组,并且切割或生成键的数组会占用大量内存,而68绝对不会),但也许它会起作用:)

$i = 0;
foreach( $array as $key => $item){
    if( $i++ < 21){
        continue;
    }
    echo $item . "\n";
}

使用数组切片获取子数组

通过数组切片获取数组的一部分,在普通的 foreach 循环中使用即可。

$sub = array_slice( $array, 21, null, true);
foreach( $sub as $key => $item){
    echo $item . "\n";
}

使用 next()

如果你能够在之前的foreach循环中设置内部数组指针为21(假设其中有一个带有break的循环,并且 $array[21] 不起作用),那么你可以这样做(如果数组中的数据 === false ,则无法正常工作):

while( ($row = next( $array)) !== false){
  echo $row;
}

顺便说一句:我最喜欢hakre的回答。


使用ArrayIterator

可能最好的评论就是研究文档。

// Initialize array iterator
$obj = new ArrayIterator( $array);
$obj->seek(21); // Set to right position
while( $obj->valid()){ // Whether we do have valid offset right now
    echo $obj->current() . "\n";
    $obj->next(); // Switch to next object
}

17
$i = 0;
foreach ($query)
{
  if ($i++ < 20) continue;

  /* php code to execute if record 21+ */
}

1
@hakre 我会给你-1的编辑分数,因为你从条件中删除了 {}。 :) - Vyktor

7

如果想要跳过某些索引,则可以创建一个包含跳过索引的数组,并在foreach循环中使用in_array函数进行检查,如果匹配则跳过。

示例:

//you have an array like that
$data = array(
    '1' => 'Hello world',
    '2' => 'Hello world2',
    '3' => 'Hello world3',
    '4' => 'Hello world4',
    '5' => 'Hello world5',// you want to skip this
    '6' => 'Hello world6',// you want to skip this
    '7' => 'Hello world7',
    '8' => 'Hello world8',
    '9' => 'Hello world8',
    '10' => 'Hello world8',//you want to skip this
);

//Ok Now wi make an array which contain the index wich have to skipped

$skipped = array('5', '6', '10');

foreach($data as $key => $value){
    if(in_array($key, $skipped)){
        continue;
    }
    //do your stuf
}

我应该使用索引还是可以直接使用值?例如:if(in_array($key, array('Hello world5'))){ continue; } 这个例子是为了跳过记录中的一个。 - Jafar

3

您没有说明"records"到底是什么,因此我不知道,我假设有一个可用的RecordIterator(如果没有,很可能有其他适合的迭代器可用):

$recordsIterator = new RecordIterator($records);
$limited = new LimitIterator($recordsIterator, 20);
foreach($limited as $record)
{
    ...
}

答案是使用带有LimitIteratorforeach

另请参阅:如何在PHP中从特定索引开始循环foreach


@webbiedave:那个类型/名称是典范的。如果$records实际上只是一个数组,那么它将是ArrayIterator。但TS没有给出任何关于记录是什么的信息(只告诉它是可以遍历的东西,这可能是一个对象、一个数组或一些*Iterator)。 - hakre

2

我不确定为什么你要使用foreach来达成这个目标,没有你的代码很难说这是否是最佳方法。但是,假设有充分的理由使用它,以下是我能想到的最简洁版本:

$count = 0;
foreach( $someArray as $index => $value ){
    if( $count++ < 20 ){
        continue;
    }

    // rest of foreach loop goes here
}
< p > continue语句会导致foreach循环跳过当前元素,直接进入下一次循环。在foreach循环中,它非常有用,可以忽略你不想处理的数组元素。


0
    array.forEach(function(element,index){
        if(index >= 21){
            //Do Something
        }
    });

Element将是索引的当前值。 每次循环时,索引都会增加。 例如0、1、2、3、4、5; 数组[index];


0
for($i = 20; $i <= 68; $i++){
//do stuff
}

这比foreach循环更好,因为它只循环你想要的元素。如果有任何问题,请问。


假设索引是连续的。可能需要先运行 array_values - webbiedave

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