PHP - elegant (fast) way to access elements counting from end of array? - php

I've got an array where I want to grab the "negative three" element regardless of array length. (If that doesn't make sense throw out a comment and I'll clarify).
The obvious way to do it is $arr[count($arr)-4] but this feels clunky.
Is there a quick, elegant way to do this?
UPDATE
Still fiddling, any thoughts regarding this?
array_slice($arr,-4,-3);

The obvious way returns the single value you want in constant time, assuming you have numeric indexes. The array size is known to PHP already, it just jumps to the offset you want and gives you the result.
array_slice does many times as much work, comparing the array size to your offset, computing the loop conditions, creating a new array to store the slice, looping over the portion of the existing array, copying the values into the new array, then returning that array to you.
http://lxr.php.net/opengrok/xref/PHP_TRUNK/ext/standard/array.c

Yes there is:
Try something like this:
$newArray = array_slice($array, -3);

you could use $last = end($arr); then use prev($arr); twice to get 2 other elements.
Oh, and check if these return FALSE, in case you don't have at least 3 elements.

array_slice()?
array_slice($a, -3)

Try array_slice() function, giving negative offset as a second parameter.

Related

Why should I use reset($arr) instead of $arr[0] in php to yield the first element of an Array in php? [duplicate]

Which one would you use?
Basically I only want to get the 1st element from a array, that's it.
Well, they do different things.
array_shift($arr) takes the first element out of the array, and gives it to you.
$arr[0] just gives it to you... if the array has numeric keys.
An alternative that works for associative arrays too is reset($arr). This does move the array's internal pointer, but unless you're using those functions this is unlikely to affect you.
array_shift will actually remove the specified value from the array. Do not use it unless you really want to reduce the array!
See here: http://php.net/manual/en/function.array-shift.php
You would use $arr[ 0 ]; array_shift removes the first element from the array.
EDIT
This answer is actually somewhere between incomplete and plain out wrong but, because the comments of the two jon's I think that it should actually stay up so that others can see that discourse.
The right answer:
reset is the method to return the first defined index of the array. Even in non-associative arrays, this may not be the 0 index.
array_shift will remove and return the value which is found at reset
The OP made the assumption that $arr[0] is the first index is not accurate in that particular context.
$arr[0] only works if the array as numerical keys.
array_shift removes the element from the array and it modifies the array itself.
If you are not sure what the first key is , and you do not want to remove it from the array, you could use:
<?php
foreach($arr $k=>$v){
$value = $v;
break;
}
or even better:
<?php
reset($arr);
$value = current($arr);
If you have an associative Array you can also use reset($arr): It returns the first Element (doesn't remove), and sets the array pointer to this element.
But the fastest way is $arr[0].
Do you want to modify the arr array also? array_shift removes the first element of the array and returns it, thus the array has changed. $arr[0] merely gives you the first element.
I would use $arr[0] unless I explicitly wanted to modify the array. You may add code later to use the arr array and forget that it was modified.
given what you need, $arr[0] is preferrable, because it's faster. array_shift is used in other situations.
arrshift is more reliable and will always return the first element in the array, but this also modifies the array by removing that element.
arr[0] will fail if your array doesn't start at the 0 index, but leaves the array itself alone.
A more convoluted but reliable method is:
$keys = array_keys($arr);
$first = $arr[$keys[0]];
with array_shif you have two operations:
retrive the firs element
shift the array
if you access by index, actually you have only one operation.
If you want the first element of an array, use $arr[0] form. Advantages - Simplicity, Readability and Maintainability. Keep things straight forward.
Edit: Use index 0 only if you know that the array has default keys starting from 0.
If you don't want to change the array in question, use $arr[0] (which merely gets the first element), otherwise if you want to remove the first element of $arr from $arr, use array_shift($arr).
For example:
$arr=array(3,-6,2);
$foo=$arr[0]; //$foo==3 and $arr==array(3,-6,2).
$bar=array_shift($arr); //$bar==3 and $arr==array(-6,2).
ETA: As others have pointed out, be sure that your array isn't an associative array (ie the keys are 0,1,...,(sizeof($arr)-1)), otherwise this probably won't work.

Better way to get first element of returned array

I found myself using this:
$var=(string)array_shift(array_values($item->xpath($s)));
where $s is an xpath search string and the return is an array of objects that contain strings.
It works, but I'm not sure it's the best way to get the data I want.
I could use a tempvar, but I wanted to avoid that.
Any suggestions?
Careful with array_shift, as it will remove the element from the array stack, if you simply want the first value, you can use current:
$var = (string) current($item->xpath($s));
I believe this gives the same result.
$var=array_shift($item->xpath($s));
$var = $reset($item->xpath($s));
Note that this rewinds the array's internal pointer and returns the first element. The method current returns the element at the position the pointer happens to be in - it is not guaranteed to always be the first element.

Get arbitrary number of random elements from a php array in one line

I wanted to pull an arbitrary number of random elements from an array in php. I see that the array_rand() function pulls an arbitrary number of random keys from an array. All the examples I found online showed then using a key reference to get the actual values from the array, e.g.
$random_elements = array();
$random_keys = array_rand($source_array);
foreach ( $random_keys as $random_key ) {
$random_elements[] = $source_array[$random_key];
}
That seemed cumbersome to me; I was thinking I could do it more concisely. I would need either a function that plain-out returned random elements, instead of keys, or one that could convert keys to elements, so I could do something like this:
$random_elements = keys_to_elements(array_rand($source_array, $number, $source_array));
But I didn't find any such function(s) in the manual nor in googling. Am I overlooking the obvious?
What about usung array_flip? Just came to my mind:
$random_elements = array_rand(array_flip($source_array), 3);
First we flip the array making its values become keys, and then use array_rand.
An alternate solution would be to shuffle the array and return a slice from the start of it.
Or, if you don't want to alter the array, you could do:
array_intersect_key($source_array, array_combine(
array_rand($source_array, $number), range(1, $number)));
This is a bit hacky because array_intersect can work on keys or values, but not selecting keys from one array that match values in another. So, I need to use array_combine to turn those values into keys of another array.
You could do something like this, not tested!!!
array_walk(array_rand($array, 2), create_function('&$value,$key',
'$value = '.$array[$value].';'));

Arrays: array_shift($arr) or $arr[0]?

Which one would you use?
Basically I only want to get the 1st element from a array, that's it.
Well, they do different things.
array_shift($arr) takes the first element out of the array, and gives it to you.
$arr[0] just gives it to you... if the array has numeric keys.
An alternative that works for associative arrays too is reset($arr). This does move the array's internal pointer, but unless you're using those functions this is unlikely to affect you.
array_shift will actually remove the specified value from the array. Do not use it unless you really want to reduce the array!
See here: http://php.net/manual/en/function.array-shift.php
You would use $arr[ 0 ]; array_shift removes the first element from the array.
EDIT
This answer is actually somewhere between incomplete and plain out wrong but, because the comments of the two jon's I think that it should actually stay up so that others can see that discourse.
The right answer:
reset is the method to return the first defined index of the array. Even in non-associative arrays, this may not be the 0 index.
array_shift will remove and return the value which is found at reset
The OP made the assumption that $arr[0] is the first index is not accurate in that particular context.
$arr[0] only works if the array as numerical keys.
array_shift removes the element from the array and it modifies the array itself.
If you are not sure what the first key is , and you do not want to remove it from the array, you could use:
<?php
foreach($arr $k=>$v){
$value = $v;
break;
}
or even better:
<?php
reset($arr);
$value = current($arr);
If you have an associative Array you can also use reset($arr): It returns the first Element (doesn't remove), and sets the array pointer to this element.
But the fastest way is $arr[0].
Do you want to modify the arr array also? array_shift removes the first element of the array and returns it, thus the array has changed. $arr[0] merely gives you the first element.
I would use $arr[0] unless I explicitly wanted to modify the array. You may add code later to use the arr array and forget that it was modified.
given what you need, $arr[0] is preferrable, because it's faster. array_shift is used in other situations.
arrshift is more reliable and will always return the first element in the array, but this also modifies the array by removing that element.
arr[0] will fail if your array doesn't start at the 0 index, but leaves the array itself alone.
A more convoluted but reliable method is:
$keys = array_keys($arr);
$first = $arr[$keys[0]];
with array_shif you have two operations:
retrive the firs element
shift the array
if you access by index, actually you have only one operation.
If you want the first element of an array, use $arr[0] form. Advantages - Simplicity, Readability and Maintainability. Keep things straight forward.
Edit: Use index 0 only if you know that the array has default keys starting from 0.
If you don't want to change the array in question, use $arr[0] (which merely gets the first element), otherwise if you want to remove the first element of $arr from $arr, use array_shift($arr).
For example:
$arr=array(3,-6,2);
$foo=$arr[0]; //$foo==3 and $arr==array(3,-6,2).
$bar=array_shift($arr); //$bar==3 and $arr==array(-6,2).
ETA: As others have pointed out, be sure that your array isn't an associative array (ie the keys are 0,1,...,(sizeof($arr)-1)), otherwise this probably won't work.

Alternative to array_shift function

Ok, I need keys to be preserved within this array and I just want to shift the 1st element from this array. Actually I know that the first key of this array will always be 1 when I do this:
// Sort it by 1st group and 1st layout.
ksort($disabled_sections);
foreach($disabled_sections as &$grouplayout)
ksort($grouplayout);
Basically I'd rather not have to ksort it in order to grab this array where the key = 1. And, honestly, I'm not a big fan of array_shift, it just takes to long IMO. Is there another way. Perhaps a way to extract the entire array where $disabled_sections[1] is found without having to do a foreach and sorting it, and array_shift. I just wanna add $disabled[1] to a different array and remove it from this array altogether. While keeping both arrays keys structured the way they are. Technically, it would even be fine to do this:
$array = array();
$array = $disabled_sections[1];
But it needs to remove it from $disabled_sections. Can I use something like this approach...
$array = array();
$array = $disabled_sections[1];
$disabled_sections -= $disabled_sections[1];
Is something like the above even possible??
Thanks.
Despite there being an accepted answer to this; in case someone else stumbles across this, a way to unset the first element of an array (regardless of its key, or the order of its keys) without using array_shift is:
reset($array); // sets internal array pointer to start
unset($array[key($array)]); // key() returns key of current array element
Though I'm fairly convinced that's what array_shift does internally (so I imagine there would be no performance gain to this), excepting an additional return of the value retrieved:
$element = reset($array); // also returns element
unset($array[key($array)]);
return $element;
Just for completion's sake.
While there's no -= operator in that fashion, you can use unset to remove that element from an array:
unset(disabled_sections[1]);
But that's just implementing your own version of shift. I do wonder under what situation you're finding array_shift() to be 'slow' and how you're testing said slowness.
Numeric arrays are sorted numerical by default - no ksort is required. Maybe you should try something like
while($array = array_shift($group_of_arrays)) {
// ... do stuff
}
If you are not concerned about the order in which you pull elements out of the array, you can use "array_pop" instead of "array_shift". Since "array_pop" takes the elements off of the end of the array, no reindexing is required and performance increases dramatically. In testing with an array of about 80,000 entries I am seeing about a 90% decrease in processing time with "array_pop".

Categories