Quantcast
Viewing latest article 2
Browse Latest Browse All 34

Detecting the “actual” end of an array in PHP

Given I have an array as follows:
$array = array(‘a’, ‘b’, 0, ‘c’, null, ‘d’);Now, I can iterate through it easily with foreach of course:
foreach($array as $value){
var_dump($value);
}And all is fine and well. However, if I want to do a “peek” to see if I’m on the last element, the following won’t work:
reset($array);
while($value = current($array)){
var_dump($value);
if(next($array)){
// this won’t be accurate because of the 0 element
}
}Ok, so I do a stricter test:
if(null !== next($array)){
// this STILL won’t be accurate because of the null element
}Is the only solution to use an indexed for loop with a arithmetic peeking? I don’t see this as being viable for maintaining associative key integrity without a lot of goofing around. (I’m aware my example doesn’t exemplify this caveat, but I’d swap current() for each(), and next() for current())
Is there no foolproof way to accurately determine whether the array pointer has moved past the end of the array, regardless of array element values (null, 0, etc.)
Caveat; While of course there are plenty of solutions that exist using temporary variables, it just seems both filthy and silly that such a thing would be necessitated for this operation. I’m surprised no concise solutions exists.

Well, this is by no means a perfect solution, since array_keys() is creating a new arrayNote but here goes:
$array = array(‘alpha’, ‘b’ => ‘beta’, null, ‘g’ => ‘gamma’, false, 0, ‘delta’, null);
list($end) = array_keys(array_slice($array, -1, 1, true));
foreach($array as $key => &$value){
// do important stuff on each element
if($key !== $end){
// do important stuff on all but last element
}
}NoteI swapped out array_slice() and array_keys() so a full key-copy isn’t created. It was initially: array_slice(array_keys($array), -1);, seems like the revision would be better on memory.

Another edit for those who stumble here; these may be of use in similar situations:
// each returns the current element, but assigns to the referenced arguments
// the “peeked” values. they’re missing checks, but it’s a start.

function peek(Array &$array, &$value){
$value = next($array);
return prev($array);
}

function peek_key(Array &$array, &$key){
next($array);
$key = key($array);
return prev($array);
}

function peek_each(Array &$array, &$key, &$value){
next($array);
list($key, $value) = array(key($array), current($array));
return prev($array);
}
……………………………………….

http://www.php.net/next
Note: You won’t be able to distinguish the end of an array from a boolean FALSE element. To properly traverse an array which may contain FALSE elements, see the each() function.
while (list($key, $val) = each($fruit)) {
echo “$key => $val\n”;
}each returns an array or false. That’s very uniquely distinguishable.
……………………………………….

Whats wrong with getting a count of number of elements ? And using that to detect if I am on last element ? http://codepad.org/zTRRjLdl
$myArr = $array = array(‘a’, ‘b’, 0, ‘c’, null, ‘d’);
$count = count($myArr);
$index = 0;

foreach($myArr as $value)
{

var_dump($value);
$index++;
if($index == $count)
echo “Its the last one here Image may be NSFW.
Clik here to view.
:)
”;
}
……………………………………….

Well, this is what I ended up going with:
$array = array(‘alpha’, ‘b’ => ‘beta’, null, ‘g’ => ‘gamma’, false, 0, ‘delta’, null);

if(!empty($array)){
list($end) = array_keys(array_slice($array, -1, 1, true));
foreach($array as $key => &$value){
// do important stuff on each element
if($key !== $end){
// do important stuff on all but last element
}
}
}Regardless, feel free to answer if you have a better solution. This works, but I’d gladly accept anything better.


Viewing latest article 2
Browse Latest Browse All 34

Trending Articles