在PHP中使用foreach循环时查找数组的最后一个元素

Find the last element of an array while using a foreach loop in PHP

我正在使用一些参数编写SQL查询创建者。在Java中,只需检查数组长度的当前数组位置,就可以很容易地从for循环中检测数组的最后一个元素。

1
2
3
for(int i=0; i< arr.length;i++){
     boolean isLastElem = i== (arr.length -1) ? true : false;        
}

在PHP中,它们具有访问数组的非整数索引。所以必须使用foreach循环迭代数组。当您需要做一些决定时(在我的例子中是在构建查询时附加或/和参数),这会变得有问题。

我相信一定有一些标准的方法来做这件事。

如何用PHP解决这个问题?


听起来你想要这样的东西:

1
2
3
4
5
6
7
$numItems = count($arr);
$i = 0;
foreach($arr as $key=>$value) {
  if(++$i === $numItems) {
    echo"last index!";
  }
}

也就是说,您不必在PHP中使用foreach迭代"数组"。


您可以使用end(array_keys($array))获取数组的最后一个键的值,并将其与当前键进行比较:

1
2
3
4
5
6
7
8
$last_key = end(array_keys($array));
foreach ($array as $key => $value) {
    if ($key == $last_key) {
        // last element
    } else {
        // not last element
    }
}


为什么这么复杂?

1
2
3
4
foreach($input as $key => $value) {
    $ret .="$value";
    if (next($input)==true) $ret .=",";
}

这将在除最后一个值之外的每个值后面添加一个!


当toend达到0时,意味着它是循环的最后一次迭代。

1
2
3
4
5
6
$toEnd = count($arr);
foreach($arr as $key=>$value) {
  if (0 === --$toEnd) {
    echo"last index! $value";
  }
}

最后一个值在循环之后仍然可用,因此如果您只想在循环之后将其用于更多内容,那么这会更好:

1
2
3
4
foreach($arr as $key=>$value) {
  //something
}
echo"last index! $key => $value";

如果不想将最后一个值视为特殊的内部循环。如果您有大的数组,这应该更快。(如果在同一范围内的循环之后重用数组,则必须首先"复制"数组)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//If you use this in a large global code without namespaces or functions then you can copy the array like this:
//$array = $originalArrayName; //uncomment to copy an array you may use after this loop

//end($array); $lastKey = key($array); //uncomment if you use the keys
$lastValue = array_pop($array);

//do something special with the last value here before you process all the others?
echo"Last is $lastValue","
"
;

foreach ($array as $key => $value) {
    //do something with all values before the last value
    echo"All except last value: $value","
"
;
}

//do something special with the last value here after you process all the others?
echo"Last is $lastValue","
"
;

并回答您最初的问题"在我的情况下,在构建查询时附加或/和参数";这将循环所有值,然后将它们连接到一个字符串中,其中"和"位于它们之间,但不在第一个值之前或最后一个值之后:

1
2
3
4
5
$params = [];
foreach ($array as $value) {
    $params[] = doSomething($value);
}
$parameters = implode(" and", $params);


已经有很多答案,但也值得研究迭代器,特别是当它被要求使用标准方法时:

1
2
3
4
5
6
7
8
9
$arr = range(1, 3);

$it = new CachingIterator(new ArrayIterator($arr));
foreach($it as $key => $value)
{
  if (!$it->hasNext()) echo 'Last:';
  echo $value,"
"
;
}

对于其他情况,您可能也会发现一些更灵活的方法。


一种方法是检测迭代器是否有next。如果没有下一个附加到迭代器,则表示您在最后一个循环中。

1
2
3
4
5
foreach ($some_array as $element) {
    if(!next($some_array)) {
         // This is the last $element
    }
}


因此,如果您的数组具有唯一的数组值,那么确定最后一次迭代是很简单的:

1
2
3
4
foreach($array as $element) {
    if ($element === end($array))
        echo 'LAST ELEMENT!';
}

如您所见,如果最后一个元素在数组中只出现一次,这就可以工作,否则会出现错误警报。在它不是,你必须比较钥匙(这是唯一的确定)。

1
2
3
4
5
foreach($array as $key => $element) {
    end($array);
    if ($key === key($array))
        echo 'LAST ELEMENT!';
}

还要注意严格的共伪运算符,这在本例中非常重要。


假设数组存储在变量中…

1
2
3
4
5
foreach($array as $key=>$value)
{
    echo $value;
    if($key != count($array)-1) { echo","; }
}


这应该是找到最后一个元素的简单方法:

1
2
3
4
5
6
7
foreach ( $array as $key => $a ) {
    if ( end( array_keys( $array ) ) == $key ) {
        echo"Last element";
     } else {
        echo"Just another element";
     }
}

参考:链接


如果您需要为除第一个或最后一个元素之外的每个元素做一些事情,并且仅当数组中有多个元素时,我更喜欢下面的解决方案。

我知道上面有很多解决方案,比我的提前了几个月/一年发布,但我觉得这本身就相当优雅。检查每个循环也是一个布尔检查,而不是数字"i=(count-1)"检查,这可能会减少开销。

循环的结构可能会感到尴尬,但您可以将其与HTML表标记中的thead(开始)、tfoot(结束)、tbody(当前)的顺序进行比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$first = true;
foreach($array as $key => $value) {
    if ($first) {
        $first = false;
        // Do what you want to do before the first element
        echo"List of key, value pairs:
"
;
    } else {
        // Do what you want to do at the end of every element
        // except the last, assuming the list has more than one element
        echo"
"
;
    }
    // Do what you want to do for the current element
    echo $key . ' => ' . $value;
}

例如,在Web开发术语中,如果您想为除无序列表(ul)中最后一个元素以外的每个元素添加一个边框底部,那么您可以将边框顶部添加到除第一个元素以外的每个元素(css:first child,由ie7+支持,firefox/webkit支持此逻辑,而ie7不支持:last child)。

您也可以自由地为每个嵌套循环重用$first变量,因为在第一次迭代的第一个过程中,每个循环都会使$first为假(因此中断/异常不会导致问题)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$first = true;
foreach($array as $key => $subArray) {
    if ($first) {
        $string ="List of key => value array pairs:
"
;
        $first = false;
    } else {
        echo"
"
;
    }

    $string .= $key . '=>(';
    $first = true;
    foreach($subArray as $key => $value) {
        if ($first) {
            $first = false;
        } else {
            $string .= ', ';
        }
        $string .= $key . '=>' . $value;
    }
    $string .= ')';
}
echo $string;

示例输出:

1
2
3
4
List of key => value array pairs:
key1=>(v1_key1=>v1_val1, v1_key2=>v1_val2)
key2=>(v2_key1=>v2_val1, v2_key2=>v2_val2, v2_key3=>v2_val3)
key3=>(v3_key1=>v3_val1)


因为你找到EOF数组的目的只是为了粘合。了解下面的策略。您不需要EOF:

1
2
3
4
5
6
7
8
9
10
$given_array = array('column1'=>'value1',
                     'column2'=>'value2',
                     'column3'=>'value3');

$glue = '';
foreach($given_array as $column_name=>$value){
    $where .=" $glue $column_name = $value"; //appending the glue
    $glue   = 'AND';
}
echo $where;

O/P:

1
column1 = value1 AND column2 = value2 AND column3 = value3

我有一种强烈的感觉,在这个"xy问题"的根源上,op只需要implode()函数。


您仍然可以将该方法用于关联数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$keys = array_keys($array);
for ($i = 0, $l = count($array); $i < $l; ++$i) {
    $key = $array[$i];
    $value = $array[$key];
    $isLastItem = ($i == ($l - 1));
    // do stuff
}

// or this way...

$i = 0;
$l = count($array);
foreach ($array as $key => $value) {
    $isLastItem = ($i == ($l - 1));
    // do stuff
    ++$i;
}


听起来你想要这样的东西:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$array = array(
    'First',
    'Second',
    'Third',
    'Last'
);

foreach($array as $key => $value)
{
    if(end($array) === $value)
    {
       echo"last index!" . $value;
    }
}


我有点喜欢以下内容,因为我觉得它相当整洁。假设我们在所有元素之间创建一个带分隔符的字符串:例如a、b、c

1
2
3
4
$first = true;
foreach ( $items as $item ) {
    $str = ($first)?$first=false:",".$item;
}


用"end"怎么样?http://php.net/manual/en/function.end.php


1
2
3
4
5
6
7
8
9
foreach ($array as $key => $value) {

  $class = ( $key !== count( $array ) -1 ) ?" class='not-last'" :" class='last'";

  echo"";
  echo"$value['the_title']";
  echo"";

}

参考


您可以执行count()。

1
2
3
for ($i=0;$i<count(arr);$i++){
    $i == count(arr)-1 ? true : false;
}

或者,如果只查找最后一个元素,则可以使用end()。

1
end(arr);

只返回最后一个元素。

而且,事实证明,您可以用整数索引PHP数组。很高兴

1
arr[1];


你也可以这样做:

1
2
3
4
5
6
7
8
9
10
11
end( $elements );
$endKey = key($elements);
foreach ($elements as $key => $value)
{
     if ($key == $endKey) // -- this is the last item
     {
          // do something
     }

     // more code
}


另一种方法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$arr = range(1, 10);

$end = end($arr);
reset($arr);

while( list($k, $v) = each($arr) )
{
    if( $n == $end )
    {
        echo 'last!';
    }
    else
    {
        echo sprintf('%s ', $v);
    }
}


如果我理解您的意思,那么您只需要反转数组并通过pop命令获取最后一个元素:

1
2
3
   $rev_array = array_reverse($array);

   echo array_pop($rev_array);


您也可以尝试使用此方法进行查询…此处显示插入

1
2
3
4
5
6
7
8
9
10
<?php
 $week=array('one'=>'monday','two'=>'tuesday','three'=>'wednesday','four'=>'thursday','five'=>'friday','six'=>'saturday','seven'=>'sunday');
 $keys = array_keys($week);
 $string ="INSERT INTO my_table ('";
 $string .= implode("','", $keys);
 $string .="') VALUES ('";
 $string .= implode("','", $week);
 $string .="');";
 echo $string;
?>


对于生成脚本的SQL查询,或者对第一个或最后一个元素执行不同操作的任何操作,避免使用不必要的变量检查的速度要快得多(几乎快两倍)。

当前接受的解决方案使用循环和循环内的检查,每次迭代都要进行检查,正确(快速)的方法如下:

1
2
3
4
5
6
7
8
9
10
$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
    $some_item=$arr[$i];
    $i++;
}
$last_item=$arr[$i];
$i++;

一个自制的小基准显示了以下内容:

试验1:100000次模型试验

时间:1869.3430423737毫秒

测试2:100000次模型运行(如果最后一次)

时间:3235.6359958649毫秒


我个人使用这种结构,它可以方便地使用html

  • 元素:只需更改其他属性的相等性…

    数组不能包含假项,但可以包含转换为假布尔值的所有其他项。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $table = array( 'a' , 'b', 'c');
    $it = reset($table);
    while( $it !== false ) {
        echo 'all loops';echo $it;
        $nextIt = next($table);
        if ($nextIt === false || $nextIt === $it) {
                echo 'last loop or two identical items';
        }
        $it = $nextIt;
    }


    end()函数更简单,它是php中的一个内置函数,用于查找给定数组的最后一个元素。函数的作用是:改变数组的内部指针指向最后一个元素,并返回最后一个元素的值。

    下面是非整数索引的示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
        $arr = array(
                'first' =>
                    array('id' => 1, 'label' => 'one'),
                'second' =>
                    array('id' => 2, 'label' => 'two'),
                'last' =>
                    array('id' => 9, 'label' => 'nine')
            );
        $lastIndexArr = end($arr);
        print_r($lastIndexArr);

    在这里检查最后一个数组作为输出。


    您可以通过以下方式直接获取最后一个索引:

    江户十一〔一〕号

    埃多克斯1〔2〕


    1
    2
    3
    4
    5
    6
    <?php foreach($have_comments as $key => $page_comment): ?>
        <?php echo $page_comment;?>
        <?php if($key+1<count($have_comments)): ?>
            <?php echo ', '; ?>
        <?php endif;?>
    <?php endforeach;?>


    我的解决方案是:只需得到数组的计数,减去1(因为它们从0开始)。

    1
    2
    3
    4
    5
    6
    $lastkey = count($array) - 1;
    foreach($array as $k=>$a){
        if($k==$lastkey){
            /*do something*/
        }
    }


    不要在最后一个值后添加逗号:

    数组:

    1
    $data = ['lorem', 'ipsum', 'dolor', 'sit', 'amet'];

    功能:

    1
    2
    3
    4
    $result ="";
    foreach($data as $value) {
        $resut .= (next($data)) ?"$value," : $value;
    }

    结果是:

    1
    print $result;

    洛伦、伊普桑、多洛、席特、阿美


    尝试这个简单的解决方案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $test = ['a' => 1, 'b' => 2, 'c' => 3];

    $last_array_value = end($test);

    foreach ($test as $key => $value) {
       if ($value === $last_array_value) {
          echo $value; // display the last value  
       } else {
         echo $value; // display the values that are not last elements
       }
    }


    另一种方法是记住前一个循环结果,并将其用作最终结果:

    1
    2
    3
    4
    5
    6
        $result = $where ="";
        foreach ($conditions as $col => $val) {
            $result = $where .= $this->getAdapter()->quoteInto($col.' = ?', $val);
            $where .= " AND";
        }
        return $this->delete($result);