I wanted to test array_shift on a simple example:
$a = ['a', 'b', 'c', 'd'];
$rem = array_shift($a);
print_r($rem);
Which only returns me: a, instead of an array of: ['b', 'c', 'd'].
php.net docs on array_shift state the following:
array_shift() shifts the first value of the array off and returns it,
shortening the array by one element and moving everything down. All
numerical array keys will be modified to start counting from zero
while literal keys won't be affected.
This function is supposed to remove the first element and return all the rest with re-ordered keys.
Now, I copied the example from the docs site as is (tried with both [] and array()):
$stack = ["orange", "banana", "apple", "raspberry"];
$fruit = array_shift($stack);
print_r($stack);
Now this returns as expected:
Array
(
[0] => banana
[1] => apple
[2] => raspberry
)
I don't understand what just happend here or what I did wrong.
My example only differs in variable names and elements in the array.
And I hardly don't believe the issue would be because of my usage of single-quotes '.
Also, here is a demo on Sandbox.
array_shift() is a stand-alone function - you don't need to assign it to a value, it automatically unsets it from the given variable:
<?php
$a = ['a', 'b', 'c', 'd'];
array_shift($a);
print_r($a);
https://3v4l.org/GEr3g
array_shift() shifts the first value of the array off and returns it
The "it" refers to "the first value", not to "the array". It shifts off the first value and returns said first value; the array is being shortened by that process. Pay close attention to what is being returned in the example code ($fruit) and what you print ($stack).
To leave the original array intact and return a new, shorter array, you'd do:
$rem = array_slice($a, 1);
In you example $rem is the return from the function array_shift as stated on the doc it will return the eliminated index value, on the other side whenever you print
print_r($a);
This will return the array after the function performed.
As the php doc array_shift shows.
The return result of array_shift is the first value of the array that been shifted off, and remove the first value of the original array.
array_shift ( array &$array ) : mixed
array_shift() shifts the first value of the array off and returns it,
shortening the array by one element and moving everything down. All
numerical array keys will be modified to start counting from zero
while literal keys won't be affected.
Related
$fruits = ['apple','cranberry','banana','cranberry'];
end($fruits);
$last_key = key($fruits);
var_dump($fruits[$last_key]) // result : cranberry
$fruits = ['apple','cranberry','banana','cranberry'];
$last_key = key($fruits);
var_dump($fruits[$last_key]) // result : apple
As you can see, the results of the two codes are different.
It seems to be the difference in the return value of end(), so I looked up the documentation.
https://www.php.net/manual/en/function.end.php
they said "Returns the value of the last element or false for empty array."
If it's like this i wondered if it was a parameter difference.
Parameters:
"The array. This array is passed by reference because it is modified by the function. This means you must pass it a real variable and not a function returning an array because only actual variables may be passed by reference."
I think I've found the answer...(...it is modified by the function.) but...
When I var_dump($fruits), there is no difference in value.
var_dump($fruits);
I do not understand it well...I'm sorry, but can explain in detail?
The end() function is an inbuilt function in PHP and is used to find the last element of the given array. The end() function changes the internal pointer of an array to point to the last element and returns the value of the last element.
<?php
// Input array
$arr = array('X', 'Y', 'Z');
// end function print the last
// element of the array.
echo end($arr);
// Output - Z
?>
Another example
<?php
// Input array
$arr = array('1', '3', '4');
// end function print the last
// element of the array.
echo end($arr)."\n";
// end() updates the internal pointer
// to point to last element as the
// current() function will now also
// return last element
echo current($arr);
?>
Output - 4
4
All I need to two is remove the final two elements from an array, which only contains 3 elements, output those two removed elements and then output the non-removed element. I'm having trouble removing the two elements, as well as keeping their keys.
My code is here http://pastebin.com/baV4fMxs
It is currently outputting : Java
Perl
Array
I want it to output:
[One] => Perl and [Two] => Java
[Zero] => PHP
$last=array_splice($inputarray,-1);
//$last has now key=>value of last element
$middle=array_splice($inputarray,-1);
//$middle has now key=>value of middle element
//$inputarray has now only key=>value of first element
It seems to me that you want to retrieve those two values being removed before getting rid of them. With this in mind, I suggest the use of array_pop() which simultaneously returns the last item in the array and removes it from the array.
$val = array_pop($my_array);
echo $val; // Last value
$val = array_pop($my_array);
echo $val; // Middle value
// Now, $my_array has only the first value
You mentioned keys, so I assume it's an associative array. In order to remove an element, you can call the unset function, like this:
unset ($my_array['my_key'])
Do this for both elements that you want to remove.
array_pop will do it for you quite easily:
$array = array( 'one', 'two', 'three');
$last = array_pop( $array); echo $last . "\n";
$second = array_pop( $array); echo $second . "\n";
echo $array[0];
Output:
three
two
one
Demo
I have an array with 4 values. I would like to remove the value at the 2nd position and then have the rest of the key's shift down one.
$b = array(123,456,789,123);
Before Removing the Key at the 2nd position:
Array ( [0] => 123 [1] => 456 [2] => 789 [3] => 123 )
After I would like the remaining keys to shift down one to fill in the space of the missing key
Array ( [0] => 123 [1] => 789 [2] => 123 )
I tried using unset() on the specific key, but it would not shift down the remaining keys. How do I remove a specific key in an array using php?
You need array_values($b) in order to re-key the array so the keys are sequential and numeric (starting at 0).
The following should do the trick:
$b = array(123,456,789,123);
unset($b[1]);
$b = array_values($b);
echo "<pre>"; print_r($b);
It is represented that your input data is an indexed array (there are no gaps in the sequence of the integer keys which start from zero). I'll compare the obvious techniques that directly deliver the desired result from the OP's sample data.
1. unset() then array_values()
unset($b[1]);
$b = array_value($b);
This is safe to use without checking for the existence of the index -- if missing, there will be no error.
unset() can receive multiple parameters, so if more elements need to be removed, then the number of function calls remains the same. e.g. unset($b[1], $b[3], $b[5]);
unset() cannot be nested inside of array_values() to form a one-liner because unset() modifies the variable and returns no value.
AFAIK, unset() is not particularly handy for removing elements using a dynamic whitelist/blacklist of keys.
2. array_splice()
array_splice($b, 1, 1);
// (input array, starting position, number of elements to remove)
This function is key-ignorant, it will target elements based on their position in the array. This is safe to use without checking for the existence of the position -- if missing, there will be no error.
array_splice() can remove a single element or, at best, remove multiple consecutive elements. If you need to remove non-consecutive elements you would need to make additional function calls.
array_splice() does not require an array_values() call because "Numerical keys in input are not preserved" -- this may or may not be desirable in certain situations.
3. array_filter() nested in array_values()
array_values(
array_filter(
$b,
function($k) {
return $k != 1;
},
ARRAY_FILTER_USE_KEY
)
)
This technique relies on a custom function call and a flag to tell the filter to iterate only the keys.
It will be a relatively poor performer because it will iterate all of the elements regardless of the logical necessity.
It is the most verbose of the options that I will discuss.
It further loses efficiency if you want to employ an in_array() call with a whitelist/blacklist of keys in the custom function.
Prior to PHP7.4, passing a whitelist/blacklist/variable into the custom function scope will require the use of use().
It can be written as a one-liner.
This is safe to use without checking for the existence of the index(es) -- if missing, there will be no error.
4. array_diff_key() nested in array_values()
array_values(
array_diff_key(
$b,
[1 => '']
)
);
This technique isn't terribly verbose, but it is a bit of an overkill if you only need to remove one element.
array_diff_key() really shines when there is a whitelist/blacklist array of keys (which may have a varying element count). PHP is very swift at processing keys, so this function is very efficient at the task that it was designed to do.
The values in the array which is declared as the second parameter of array_diff_key() are completely irrelevant -- they can be null or 999 or 'eleventeen' -- only the keys are respected.
array_diff_key() does not have any scoping challenges, compared to array_filter(), because there is no custom function called.
It can be written as a one-liner.
This is safe to use without checking for the existence of the index(es) -- if missing, there will be no error.
Use array_splice().
array_splice( $b, 1, 1 );
// $b == Array ( [0] => 123 [1] => 789 [2] => 123 )
No one has mentioned this, so i will do: sort() is your friend.
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
foreach($fruits as $key => $val)
echo "fruits[$key] = $val";
output:
fruits[0] = apple
fruits[1] = banana
fruits[2] = lemon
fruits[3] = orange
// remove Lemon, too bitter
unset($fruits[2]);
// keep keys with asort
asort($fruits);
foreach($fruits as $key => $val)
echo "fruits[$key] = $val";
Output:
fruits[0] = apple
fruits[1] = banana
fruits[3] = orange
This is the one you want to use to reindex the keys:
// reindex keys with sort
sort($fruits);
foreach($fruits as $key => $val)
echo "fruits[$key] = $val";
Output:
fruits[0] = apple
fruits[1] = banana
fruits[2] = orange
If you want to remove an item from an array at a specific position, you can obtain the key for that position and then unset it:
$b = array(123,456,789,123);
$p = 2;
$a = array_keys($b);
if ($p < 0 || $p >= count($a))
{
throw new RuntimeException(sprintf('Position %d does not exists.', $p));
}
$k = $a[$p-1];
unset($b[$k]);
This works with any PHP array, regardless where the indexing starts or if strings are used for keys.
If you want to renumber the remaining array just use array_values:
$b = array_values($b);
Which will give you a zero-based, numerically indexed array.
If the original array is a zero-based, numerically indexed array as well (as in your question), you can skip the part about obtaining the key:
$b = array(123,456,789,123);
$p = 2;
if ($p < 0 || $p >= count($b))
{
throw new RuntimeException(sprintf('Position %d does not exists.', $p));
}
unset($b[$p-1]);
$b = array_values($b);
Or directly use array_splice which deals with offsets instead of keys and re-indexes the array (numeric keys in input are not preserved):
$b = array(123,456,789,123);
$p = 2;
if ($p < 0 || $p >= count($b))
{
throw new RuntimeException(sprintf('Position %d does not exists.', $p));
}
array_splice($b, $p-1, 1);
I have an array like this:
array[0] = "hello0"
array[1] = "hello1"
array[2] = "hello2"
Now I want to get the last key '2' of the array. I cant use end() because that will return the value 'hello2'.
What function should I use?
end() not only returns the value of the last element but also sets the internal pointer to the last element. And key() returns the key of the element this internal pointer currently ...err... points to.
$a = array(1=>'a', 5=>'b', 99=>'d');
end($a);
echo key($a);
prints 99
If the keys are not continuous (i.e. if you had keys 1, 5, 7, for example):
$highest_key = rsort(array_keys($myarray))[0];
If they are continuous, just use count($myarray)-1.
count($array) - 1
Won't work if you've added non-numeric keys or non-sequential keys.
Is there a PHP function that would 'pop' first element of array?
array_pop() pops last element, but I'd like to pop the first.
You are looking for array_shift().
PHP Array Shift
Quick Cheatsheet If you are not familiar with the lingo, here is a quick translation of alternate terms, which may be easier to remember:
* array_unshift() - (aka Prepend ;; InsertBefore ;; InsertAtBegin )
* array_shift() - (aka UnPrepend ;; RemoveBefore ;; RemoveFromBegin )
* array_push() - (aka Append ;; InsertAfter ;; InsertAtEnd )
* array_pop() - (aka UnAppend ;; RemoveAfter ;; RemoveFromEnd )
While array_shift() is definitely the answer to your question, it's worth mentioning that it can be an unnecessarily slow process when working with large arrays. (or many iterations)
After retrieving the first element, array_shift() re-indexes all numerical keys in an array, so that the element that used to be at [1] becomes [0] and an element at [10000] becomes [9999].
The larger the array, the more keys to re-index. And if you're iterating over large arrays, calling array_shift on multiple iterations, the performance hit can rack up.
Benchmarks show for large arrays it's often cheaper to reverse the array order and pop the elements from the end.
$array = array_reverse($array);
$value = array_pop($array);
array_pop() obviously doesn't need to re-index since it's taking from the end, and array_reverse() returns a new array by simply copying the array passed to it, from back to front. array_reverse($array, true) can be used to preserve key => value pairs where needed.
[EDIT] I should mention, the downside to the reverse-pop method is memory consumption, where array_reverse() generates a new array, while array_shift() works in place. Thus takes longer.
For me array_slice() works fine,
Say:
$arr = array(1,2,3,4,5,6);
//array_slice($array,offset); where $array is the array to be sliced, and offset is the number of array elements to be sliced
$arr2 = array_slice($arr,3);//or
$arr2 = array_slice($arr,-3);//or
$arr2 = array_slice($arr,-3,3);//return 4,5 and 6 in a new array
$arr2 = array_slice($arr,0,4);//returns 1,2,3 and 4 in a new array
Use key() and unset().
When array's keys is Numeric, array_shift() change array keys to started from 0.
$arr = [5 => 5, 71 => 71, 1 => 1, 8 => 8];
$first_key = key($arr);
$first_element = $arr[$first_key]; // <-- get first element of array
echo $first_element; // print '5'
unset($arr[]); // <-- delete first element of array