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 Note but here goes:array_keys()
is creating a new array
$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);
}