88

Please help me to translate this pseudo-code to real php code:

 foreach ($arr as $k => $v)
    if ( THIS IS NOT THE LAST ELEMENT IN THE ARRAY)
        doSomething();

Edit: the array may have numerical or string keys

shealtiel
  • 8,020
  • 18
  • 50
  • 82
  • 6
    Why not use `for` loop for `count($arr) - 1` iterations? – Marcin May 23 '11 at 01:44
  • 1
    If you have mixed keys, how do you determine which key is the last item? If you want it as the last item added to the array, then there should be some data to indicate a time stamp. – Rasika May 23 '11 at 01:53
  • definition for last: by the inner order of the array. Which is identical to saying the last element that the foreach loop will pick – shealtiel May 23 '11 at 02:32
  • Related: [How to get last key in an array?](https://stackoverflow.com/q/2348205/2943403) – mickmackusa May 18 '22 at 04:04

8 Answers8

153

you can use PHP's end()

$array = array('a' => 1,'b' => 2,'c' => 3);
$lastElement = end($array);
foreach($array as $k => $v) {
    echo $v . '<br/>';
    if($v == $lastElement) {
         // 'you can do something here as this condition states it just entered last element of an array'; 
    }
}

Update1

as pointed out by @Mijoja the above could will have problem if you have same value multiple times in array. below is the fix for it.

$array = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 2);
//point to end of the array
end($array);
//fetch key of the last element of the array.
$lastElementKey = key($array);
//iterate the array
foreach($array as $k => $v) {
    if($k == $lastElementKey) {
        //during array iteration this condition states the last element.
    }
}

Update2

I found solution by @onteria_ to be better then what i have answered since it does not modify arrays internal pointer, i am updating the answer to match his answer.

$array = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 2);
// Get array keys
$arrayKeys = array_keys($array);
// Fetch last array key
$lastArrayKey = array_pop($arrayKeys);
//iterate array
foreach($array as $k => $v) {
    if($k == $lastArrayKey) {
        //during array iteration this condition states the last element.
    }
}

Thank you @onteria_

Update3

As pointed by @CGundlach PHP 7.3 introduced array_key_last which seems much better option if you are using PHP >= 7.3

$array = array('a' => 1,'b' => 2,'c' => 3);
$lastKey = array_key_last($array);
foreach($array as $k => $v) {
    echo $v . '<br/>';
    if($k == $lastKey) {
         // 'you can do something here as this condition states it just entered last element of an array'; 
    }
}
Ibrahim Azhar Armar
  • 25,288
  • 35
  • 131
  • 207
  • 13
    This will have problems if you have the same value multiple times in the array – Mijoja Apr 10 '12 at 19:51
  • 2
    @IbrahimAzharArmar Just found this answer and while implementing your solution I noticed that since PHP 7.3 there is now the function `array_key_last`, which also returns the last key of an array without affecting the internal pointer: https://secure.php.net/array_key_last. Would simplify your solution even more :) – CGundlach Sep 02 '19 at 12:47
  • 1
    @CGundlach that's good to know. Will update the answer. Thank you. – Ibrahim Azhar Armar Sep 03 '19 at 09:47
27

This always does the trick for me

foreach($array as $key => $value) {
   if (end(array_keys($array)) == $key)
       // Last key reached
}

Edit 30/04/15

$last_key = end(array_keys($array));
reset($array);

foreach($array as $key => $value) {
  if ( $key == $last_key)
      // Last key reached
}

To avoid the E_STRICT warning mentioned by @Warren Sergent

$array_keys = array_keys($array);
$last_key = end($array_keys);
Richard Merchant
  • 983
  • 12
  • 10
  • 2
    @Pierce to give you a hint: this was answered 3 and a half years after the accepted answer, plus if you have a 1000 items in your array, you will call "end" 1000 times and "array_keys" 1000 times. – StefanNch Apr 10 '15 at 15:38
  • This clearly has performance issues if you are iterating over a large array. My suggestion in that case is to move the end(array_keys($array)) outside the loop. But make sure you reset the array before the iteration. – Richard Merchant Apr 30 '15 at 13:06
  • If you want to be pedantic, under strict mode, end(array_keys($array)) will cause a notice, as "Only variables should be passed by reference" - to correct this, define $array_keys = array_keys($array) and call end() on the $array_keys variable. – Warren Sergent Dec 02 '15 at 00:58
  • @WarrenSergent, or jou can just use double parenthesis to avoid strict notice, https://stackoverflow.com/questions/20776017/why-am-i-getting-only-variables-should-be-passed-by-reference-error – Danijel Nov 08 '18 at 16:41
  • @Danijel Whilst that's true, I wouldn't necessarily rely on suppressing or 'avoiding' the notice. The double parenthesis issue has some interesting discussion here too regarding whether this could be considered a BUG in PHP itself: https://stackoverflow.com/questions/6726589/parentheses-altering-semantics-of-function-call-result – Warren Sergent Nov 09 '18 at 22:24
14
$myarray = array(
  'test1' => 'foo',
  'test2' => 'bar',
  'test3' => 'baz',
  'test4' => 'waldo'
);

$myarray2 = array(
'foo',
'bar',
'baz',
'waldo'
);

// Get the last array_key
$last = array_pop(array_keys($myarray));
foreach($myarray as $key => $value) {
  if($key != $last) {
    echo "$key -> $value\n";
  }
}

// Get the last array_key
$last = array_pop(array_keys($myarray2));
foreach($myarray2 as $key => $value) {
  if($key != $last) {
    echo "$key -> $value\n";
  }
}

Since array_pop works on the temporary array created by array_keys it doesn't modify the original array at all.

$ php test.php
test1 -> foo
test2 -> bar
test3 -> baz
0 -> foo
1 -> bar
2 -> baz
onteria_
  • 68,181
  • 7
  • 71
  • 64
7

Why not this very simple method:

$i = 0; //a counter to track which element we are at
foreach($array as $index => $value) {
    $i++;
    if( $i == sizeof($array) ){
        //we are at the last element of the array
    }
}
Mohammad Usman
  • 37,952
  • 20
  • 92
  • 95
PreciousFocus
  • 71
  • 1
  • 1
  • Why not? Because it pointless to call `sizeof()` inside of a loop. The array's size never changes, so why keep calling a function that returns the count? More importantly, PHP now has `array_key_last()` which is more direct and is not limited to handling indexed arrays. – mickmackusa May 18 '22 at 04:00
3

I know this is old, and using SPL iterator maybe just an overkill, but anyway, another solution here:

$ary = array(1, 2, 3, 4, 'last');
$ary = new ArrayIterator($ary);
$ary = new CachingIterator($ary);
foreach ($ary as $each) {
    if (!$ary->hasNext()) { // we chain ArrayIterator and CachingIterator
                            // just to use this `hasNext()` method to see
                            // if this is the last element
       echo $each;
    }
}
unifreak
  • 773
  • 6
  • 17
2

My solution, also quite simple..

$array = [...];
$last = count($array) - 1;

foreach($array as $index => $value) 
{
     if($index == $last)
        // this is last array
     else
        // this is not last array
}
Edwin Wong
  • 703
  • 1
  • 8
  • 11
  • This is pretty nice and simple, as long as your array keys have been auto-generated. – Matt Kieran Mar 29 '19 at 19:21
  • There is no longer a reason to leverage a situationally-dependent technique like this because PHP now has `array_key_last()`. See the accepted answer. – mickmackusa May 18 '22 at 03:58
0

If the items are numerically ordered, use the key() function to determine the index of the current item and compare it to the length. You'd have to use next() or prev() to cycle through items in a while loop instead of a for loop:

$length = sizeOf($arr);
while (key(current($arr)) != $length-1) {
    $v = current($arr); doSomething($v); //do something if not the last item
    next($myArray); //set pointer to next item
}
trusktr
  • 44,284
  • 53
  • 191
  • 263
0

Simple approach using array_keys function to get the keys and get only first key [0] of reversed array which is the last key.

$array = array('a' => 1,'b' => 2,'c' => 3);
$last_key = array_keys(array_reverse($array, true))[0];
foreach($array as $key => $value) {
   if ($last_key !== $key)
       // THIS IS NOT THE LAST ELEMENT IN THE ARRAY doSomething();
}

NOTE: array_reverse reverse array take two arguments first array we want be reversed and second parameter true, to reverse the array and preserves the order of keys.

XMehdi01
  • 5,538
  • 2
  • 10
  • 34