tags:

views:

9949

answers:

13

I am writing a sql query creator using some parameters. While doing that ,I came across this problem. In java , Its very easy to detect the last element of an array from inside the for loop by just checking the current array position with the array length.

for(int i=0; i< arr.length;i++){

     boolean isLastElem = i== (arr.length -1) ? true : false;        

}

php has some different fashion. They have non integer indexes to access arrays. So you must iterate over an array using foreach loop. But it becomes very problematic when you need to take some decision (in my case to append or/and parameter while building query).

I am sure there must be some standard way of doing this.

How do you solve this problem normally in php ?

+1  A: 

you can do a count().

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

or if you're looking for ONLY the last element, you can use end().

end(arr);

returns only the last element.

and, as it turns out, you CAN index php arrays by integers. It's perfectly happy with

arr[1];
contagious
+11  A: 

It sounds like you want something like this:

$numItems = count($arr);
$i = 0;
foreach($arr as $key=>$value) {
  if($i == $numItems) {
    echo "last index!";
  }
  $i++;
}

That being said, you don't -have- to iterate over an "array" using foreach in php.

Richard Levasseur
I think I will go for this solution as it is almost similar to the code I posted. Even Jeremy's answer is well fit but I think it got little complex compared to this one. I have not ran any tests but I guess this answer shall be faster as it is not extracting array of keys.This shall have O(1) speed
Vaibhav Kamble
Shouldn't $i = 1 because Count starts at 1 and not 0?
Paul Sheldrake
+9  A: 

You could get the value of the last key of the array using end(array_keys($array)) and compare it to the current key:

$last_key = end(array_keys($array));
foreach ($array as $key => $value) {
    if ($key == $last_key) {
        // last element
    } else {
        // not last element
    }
}
yjerem
+1 I agree - the other solutions rely on the array having numeric indexes.
Patrick Daryll Glandien
In my own defense, my answer doesn't rely on the array having numeric keys :)
Richard Levasseur
string comparison is slower then integers, and not always accurate when comparing strings to integers (you should at least have used ===). Im voting this down.
OIS
+1  A: 

You can still use that method with associative arrays:

$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;
}
nickf
+2  A: 
$toEnd = count($arr);
foreach($arr as $key=>$value) {
  if (0 === --$toEnd) {
    echo "last index! $value";
  }
}

or the best way is probably this if you still execute the other loop code

foreach($arr as $key=>$value) {
  //something
}
echo "last index! $key => $value";
OIS
In this example, it will perform the --$toEnd in every iteration in the loop, so I would recommend moving that outside of the foreach loop so you can perform a direct comparison on an already calculated value.
Sohnee
Of course it will perform the --$toEnd for every iteration, thats the point. If I moved it outside the loop, it would not work anymore.
OIS
A: 

You could also do something like this:

$endKey = key(end( $elements ));
foreach ($elements as $key => $value)
{
     if ($key == $endKey) // -- this is the last item
     {
          // do something
     }

     // more code
}
KOGI
end returns the value not the array, so the way you made it doesnt work. string comparison is also slower then integer.
OIS
You are right. it should be end($elements); $endKey = key($elements);
KOGI
A: 

no your all wrong its this

public boolean add(int num) {
int index = data.length; if(index < this.count) { data[index +1] = num; return true;

boo
A: 

Here's another way you could do it:

$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);
    }
}
Kevin
+2  A: 

why so complicated?

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

This will add a , behind every value except the last one!

Trikks
+1  A: 

If you need to do something for every element except either the first or the last and only if there is more than one element in the array, I prefer the following solution.

I know there are many solutions above and posted months/one year before mine, but this is something I feel is fairly elegant in its own right. The check every loop is also a boolean check as opposed to a numeric "i=(count-1)" check, which may allow for less overhead.

The structure of the loop may feel awkward, but you can compare it to the ordering of thead (beginning), tfoot (end), tbody (current) in HTML table tags.

$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:\n";
    } 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 "\n";
    }
    // Do what you want to do for the current element
    echo $key . ' => ' . $value;
}

For instance, in web development terms, if you want to add a border-bottom to every element except the last in an unordered list (ul), then you can instead add a border-top to every element except the first (the CSS :first-child, supported by IE7+ and Firefox/Webkit supports this logic, whereas :last-child is not supported by IE7).

You can feel free to reuse the $first variable for each and every nested loop as well and things will work just fine since every loop makes $first false during the first process of the first iteration (so breaks/exceptions won't cause issues).

$first = true;
foreach($array as $key => $subArray) {
    if ($first) {
        $string = "List of key => value array pairs:\n";
        $first = false;
    } else {
        echo "\n";
    }

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

Example output:

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)
Ankit Aggarwal
A: 

Hi, If I understand you, then all you need is to reverse the array and get the last element by a pop command:

   $rev_array = array_reverse($array);

   echo array_pop($rev_array);
James
+1  A: 

How about using "end"? http://php.net/manual/en/function.end.php

Çağ