PHP | Remove element from array with reordering? - php

How can I remove an element of an array, and reorder afterwards, without having an empty element in the array?
<?php
$c = array( 0=>12,1=>32 );
unset($c[0]); // will distort the array.
?>
Answer / Solution: array array_values ( array $input ).
<?php
$c = array( 0=>12,1=>32 );
unset($c[0]);
print_r(array_values($c));
// will print: the array cleared
?>

array_values($c)
will return a new array with just the values, indexed linearly.

If you are always removing the first element, then use array_shift() instead of unset().
Otherwise, you should be able to use something like $a = array_values($a).

Another option would be array_splice(). This reorders numeric keys and appears to be a faster method if you are crunching enough data to care. But I like unset() array_values() for readability.
array_splice( $array, $index, $num_elements_to_remove);
http://php.net/manual/en/function.array-splice.php
Speed test:
ArraySplice process used 7468 ms for its computations
ArraySplice spent 918 ms in system calls
UnsetReorder process used 9963 ms for its computations
UnsetReorder spent 31 ms in system calls
Test Code:
function rutime($ru, $rus, $index) {
return ($ru["ru_$index.tv_sec"]*1000 + intval($ru["ru_$index.tv_usec"]/1000))
- ($rus["ru_$index.tv_sec"]*1000 + intval($rus["ru_$index.tv_usec"]/1000));
}
function time_output($title, $rustart, $ru) {
echo $title . " process used " . rutime($ru, $rustart, "utime") .
" ms for its computations\n";
echo $title . " spent " . rutime($ru, $rustart, "stime") .
" ms in system calls\n";
}
$test = array();
for($i = 0; $i<100000; $i++){
$test[$i] = $i;
}
$rustart = getrusage();
for ($i = 0; $i<1000; $i++){
array_splice($test,90000,1);
}
$ru = getrusage();
time_output('ArraySplice', $rustart, $ru);
unset($test);
$test = array();
for($i = 0; $i<100000; $i++){
$test[$i] = $i;
}
$rustart = getrusage();
for ($i = 0; $i<1000; $i++){
unset($test[90000]);
$test = array_values($test);
}
$ru = getrusage();
time_output('UnsetReorder', $rustart, $ru);

If you only remove the first item of the array, you could use array_shift($c);

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 touched.
array_shift($stack);
example:
$stack = array("orange", "banana", "apple", "raspberry");
$fruit = array_shift($stack);
print_r($stack);
Output:
Array
(
[0] => banana
[1] => apple
[2] => raspberry
)
Source: http://php.net/manual/en/function.array-shift.php

$array=["one"=>1,"two"=>2,"three"=>3];
$newArray=array_shift($array);
return array_values($newArray);
return [2,3]
array_shift remove first element from an array
array_values return just values

Or reset(); is also a good choice

Related

how to access a json_decoded array with string keys/indizes via integer numbers [duplicate]

What's the best way to determine the first key in a possibly associative array? My first thought it to just foreach the array and then immediately breaking it, like this:
foreach ($an_array as $key => $val) break;
Thus having $key contain the first key, but this seems inefficient. Does anyone have a better solution?
2019 Update
Starting from PHP 7.3, there is a new built in function called array_key_first() which will retrieve the first key from the given array without resetting the internal pointer. Check out the documentation for more info.
You can use reset and key:
reset($array);
$first_key = key($array);
It's essentially the same as your initial code, but with a little less overhead, and it's more obvious what is happening.
Just remember to call reset, or you may get any of the keys in the array. You can also use end instead of reset to get the last key.
If you wanted the key to get the first value, reset actually returns it:
$first_value = reset($array);
There is one special case to watch out for though (so check the length of the array first):
$arr1 = array(false);
$arr2 = array();
var_dump(reset($arr1) === reset($arr2)); // bool(true)
array_keys returns an array of keys. Take the first entry. Alternatively, you could call reset on the array, and subsequently key. The latter approach is probably slightly faster (Thoug I didn't test it), but it has the side effect of resetting the internal pointer.
Interestingly enough, the foreach loop is actually the most efficient way of doing this.
Since the OP specifically asked about efficiency, it should be pointed out that all the current answers are in fact much less efficient than a foreach.
I did a benchmark on this with php 5.4, and the reset/key pointer method (accepted answer) seems to be about 7 times slower than a foreach. Other approaches manipulating the entire array (array_keys, array_flip) are obviously even slower than that and become much worse when working with a large array.
Foreach is not inefficient at all, feel free to use it!
Edit 2015-03-03:
Benchmark scripts have been requested, I don't have the original ones but made some new tests instead. This time I found the foreach only about twice as fast as reset/key. I used a 100-key array and ran each method a million times to get some noticeable difference, here's code of the simple benchmark:
$array = [];
for($i=0; $i < 100; $i++)
$array["key$i"] = $i;
for($i=0, $start = microtime(true); $i < 1000000; $i++) {
foreach ($array as $firstKey => $firstValue) {
break;
}
}
echo "foreach to get first key and value: " . (microtime(true) - $start) . " seconds <br />";
for($i=0, $start = microtime(true); $i < 1000000; $i++) {
$firstValue = reset($array);
$firstKey = key($array);
}
echo "reset+key to get first key and value: " . (microtime(true) - $start) . " seconds <br />";
for($i=0, $start = microtime(true); $i < 1000000; $i++) {
reset($array);
$firstKey = key($array);
}
echo "reset+key to get first key: " . (microtime(true) - $start) . " seconds <br />";
for($i=0, $start = microtime(true); $i < 1000000; $i++) {
$firstKey = array_keys($array)[0];
}
echo "array_keys to get first key: " . (microtime(true) - $start) . " seconds <br />";
On my php 5.5 this outputs:
foreach to get first key and value: 0.15501809120178 seconds
reset+key to get first key and value: 0.29375791549683 seconds
reset+key to get first key: 0.26421809196472 seconds
array_keys to get first key: 10.059751987457 seconds
reset+key http://3v4l.org/b4DrN/perf#tabs
foreach http://3v4l.org/gRoGD/perf#tabs
key($an_array) will give you the first key
edit per Blixt: you should call reset($array); before key($an_array) to reset the pointer to the beginning of the array.
You could try
array_keys($data)[0]
For 2018+
Starting with PHP 7.3, there is an array_key_first() function that achieve exactly this:
$array = ['foo' => 'lorem', 'bar' => 'ipsum'];
$firstKey = array_key_first($array); // 'foo'
Documentation is available here. 😉
list($firstKey) = array_keys($yourArray);
If efficiency is not that important for you, you can use array_keys($yourArray)[0] in PHP 5.4 (and higher).
Examples:
# 1
$arr = ["my" => "test", "is" => "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "my"
# 2
$arr = ["test", "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "0"
# 3
$arr = [1 => "test", 2 => "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "1"
The advantage over solution:
list($firstKey) = array_keys($yourArray);
is that you can pass array_keys($arr)[0] as a function parameter (i.e. doSomething(array_keys($arr)[0], $otherParameter)).
HTH
Please find the following:
$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$keys = array_keys($yourArray);
echo "Key = ".$keys[0];
Working Example:
$myArray = array(
2 => '3th element',
4 => 'first element',
1 => 'second element',
3 => '4th element'
);
echo min(array_keys($myArray)); // return 1
This could also be a solution:
$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$first_key = current(array_flip($yourArray));
echo $first_key;
I have tested it and it works.
Working Code.
To enhance on the solution of Webmut, I've added the following solution:
$firstKey = array_keys(array_slice($array, 0, 1, TRUE))[0];
The output for me on PHP 7.1 is:
foreach to get first key and value: 0.048566102981567 seconds
reset+key to get first key and value: 0.11727809906006 seconds
reset+key to get first key: 0.11707186698914 seconds
array_keys to get first key: 0.53917098045349 seconds
array_slice to get first key: 0.2494580745697 seconds
If I do this for an array of size 10000, then the results become
foreach to get first key and value: 0.048488140106201 seconds
reset+key to get first key and value: 0.12659382820129 seconds
reset+key to get first key: 0.12248802185059 seconds
array_slice to get first key: 0.25442600250244 seconds
The array_keys method times out at 30 seconds (with only 1000 elements, the timing for the rest was about the same, but the array_keys method had about 7.5 seconds).
$arr = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
list($first_key) = each($arr);
print $first_key;
// key1
This is the easier way I had ever found. Fast and only two lines of code :-D
$keys = array_keys($array);
echo $array[$keys[0]];
The best way that worked for me was
array_shift(array_keys($array))
array_keys gets array of keys from initial array and then array_shift cuts from it first element value.
You will need PHP 5.4+ for this.
php73:
$array = ['a' => '..', 'b' => '..'];
array_key_first($array); // 'a'
array_key_last($array); // 'b';
http://php.net/manual/en/function.array-key-first.php
Since PHP 7.3.0 function array_key_first() can be used.
There are several ways to provide this functionality for versions prior to PHP 7.3.0. It is possible to use array_keys(), but that may be rather inefficient. It is also possible to use reset() and key(), but that may change the internal array pointer. An efficient solution, which does not change the internal array pointer, written as polyfill:
<?php
if (!function_exists('array_key_first')) {
function array_key_first(array $arr) {
foreach($arr as $key => $unused) {
return $key;
}
return null;
}
}
?>
Re the #Blixt answer, prior to 7.3.0, this polyfill can be used:
if (!function_exists('array_key_first')) {
function array_key_first(array $array) {
return key(array_slice($array, 0, 1, true));
}
}
This will work on all PHP versions
$firstKey = '' ;
//$contact7formlist - associative array.
if(function_exists('array_key_first')){
$firstKey = array_key_first($contact7formlist);
}else{
foreach ($contact7formlist as $key => $contact7form ){
$firstKey = $key;
break;
}
}
A one-liner:
$array = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
echo key( array_slice( $array, 0, 1, true ) );
# echos 'key1'
Today I had to search for the first key of my array returned by a POST request. (And note the number for a form id etc)
Well, I've found this:
Return first key of associative array in PHP
http://php.net/key
I've done this, and it work.
$data = $request->request->all();
dump($data);
while ($test = current($data)) {
dump($test);
echo key($data).'<br />';die();
break;
}
Maybe it will eco 15min of an other guy.
CYA.
I think the best and fastest way to do it is:
$first_key=key(array_slice($array, 0, 1, TRUE))
array_chunk split an array into chunks, you can use:
$arr = ['uno'=>'one','due'=>'two','tre'=>'three'];
$firstElement = array_chunk($arr,1,true)[0];
var_dump($firstElement);
You can play with your array
$daysArray = array('Monday', 'Tuesday', 'Sunday');
$day = current($transport); // $day = 'Monday';
$day = next($transport); // $day = 'Tuesday';
$day = current($transport); // $day = 'Tuesday';
$day = prev($transport); // $day = 'Monday';
$day = end($transport); // $day = 'Sunday';
$day = current($transport); // $day = 'Sunday';
To get the first element of array you can use current and for last element you can use end
Edit
Just for the sake for not getting any more down votes for the answer you can convert you key to value using array_keys and use as shown above.
use :
$array = ['po','co','so'];
echo reset($array);
Result : po

I want to put specific values in for loop

For instance, i have a 2 list of values that has no relevance with each elements. I'm planning to put this values manually.
$a1 = 'red';
$a2 = '007';
$a3 = 'gun';
$a4 = 'apple';
$b1 = 'poison';
$b2 = 'movie';
$b3 = 'man';
$b4 = 'store';
echo $a.' with '.$b
I want an output like:
red with poison
007 with movie
gun with man
apple with store
So I want $an displayed with $bn. I have thought of using a for loop, but I don't know how to do it (I'm really new to PHP...)
Any suggestions? any help would be great. thanks in advance!
Use arrays :
$a[0] = 'red';
$a[1] = '007';
$a[2] = 'gun';
$a[3] = 'apple';
$b[0] = 'poison';
$b[1] = 'movie';
$b[2] = 'man';
$b[3] = 'store';
foreach($a as $key=>$value)
{
echo $value.' with '.$b[$key];
}
I think the simplest is to use a associative array and foreach like this:
foreach (array("red" => "poison",
"007" => "movie",
"gun" => "man",
"apple" => "store") as $a => $b) {
echo "$a with $b\n";
}
change your setup to an array
$a[1] = 'red';
$a[2] = '007';
$a[3] = 'gun';
$a[4] = 'apple';
$b[1] = 'poison';
$b[2] = 'movie';
$b[3] = 'man';
$b[4] = 'store';
then use a for loop
for($n=0;$n<sizeof($a);$n++){
echo $a[$n] . ' with ' . $b[$n];
}
with this method you can call any part of the variable with its known number at any time elsewhere in the script, such as:
echo $b[2];
This is an explanation on the for loop.
for() This calls the loop and is limited by { and }
The arguments in the loop start with your starter.
In my case I used $n. I set $n to 0 to give the loops somewhere to start from.
The next part of the loop is how many times you want it iterated in comparison to your start variable. This is usually dependent on the size of an array but can also be a number. The argument I created here to determine the iterations. sizeof() is another function within php to get the number of elements within an array or variable (or i think it can do file sizes too). I am telling it to make sure that as long as $n is less than the size of the variable to keep looping. You normally want a loop to end after a while else pages take forever to load.
Finally you add the thing at the end to increase the counter so to speak. This can be anything once again but using $n++ means it increases the value of $n by 1 each time until the end of the loop
You can use arrays:
//that's how you add elements to an array
$a[] = 'red';
$a[] = '007';
$a[] = 'gun';
$a[] = 'apple';
$b[] = 'poison';
$b[] = 'movie';
$b[] = 'man';
$b[] = 'store';
//and this is how you read from an array
for($i=0; $i<count($a); $i++){
echo $a[$i].' with '.$b[$i] . "\n";
}
for (var $i = 1; $i <= 4; $i++) {
echo ${"a".$i} . " with " . ${"b".$i};
}
see http://php.net/manual/en/language.variables.variable.php

Reverse order of foreach list items

I would like to reverse the order of this code's list items. Basically it's a set of years going from oldest to recent and I am trying to reverse that output.
<?php
$j=1;
foreach ( $skills_nav as $skill ) {
$a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
$a .= $skill->name;
$a .= '</a></li>';
echo $a;
echo "\n";
$j++;
}
?>
Walking Backwards
If you're looking for a purely PHP solution, you can also simply count backwards through the list, access it front-to-back:
$accounts = Array(
'#jonathansampson',
'#f12devtools',
'#ieanswers'
);
$index = count($accounts);
while($index) {
echo sprintf("<li>%s</li>", $accounts[--$index]);
}
The above sets $index to the total number of elements, and then begins accessing them back-to-front, reducing the index value for the next iteration.
Reversing the Array
You could also leverage the array_reverse function to invert the values of your array, allowing you to access them in reverse order:
$accounts = Array(
'#jonathansampson',
'#f12devtools',
'#ieanswers'
);
foreach ( array_reverse($accounts) as $account ) {
echo sprintf("<li>%s</li>", $account);
}
Or you could use the array_reverse function.
array_reverse() does not alter the source array, but returns a new array. (See array_reverse().) So you either need to store the new array first or just use function within the declaration of your for loop.
<?php
$input = array('a', 'b', 'c');
foreach (array_reverse($input) as $value) {
echo $value."\n";
}
?>
The output will be:
c
b
a
So, to address to OP, the code becomes:
<?php
$j=1;
foreach ( array_reverse($skills_nav) as $skill ) {
$a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
$a .= $skill->name;
$a .= '</a></li>';
echo $a;
echo "\n";
$j++;
}
Lastly, I'm going to guess that the $j was either a counter used in an initial attempt to get a reverse walk of $skills_nav, or a way to count the $skills_nav array. If the former, it should be removed now that you have the correct solution. If the latter, it can be replaced, outside of the loop, with a $j = count($skills_nav).
If you don't mind destroying the array (or a temp copy of it) you can do:
$stack = array("orange", "banana", "apple", "raspberry");
while ($fruit = array_pop($stack)){
echo $fruit . "\n<br>";
}
produces:
raspberry
apple
banana
orange
I think this solution reads cleaner than fiddling with an index and you are less likely to introduce index handling mistakes, but the problem with it is that your code will likely take slightly longer to run if you have to create a temporary copy of the array first.
Fiddling with an index is likely to run faster, and it may also come in handy if you actually need to reference the index, as in:
$stack = array("orange", "banana", "apple", "raspberry");
$index = count($stack) - 1;
while($index > -1){
echo $stack[$index] ." is in position ". $index . "\n<br>";
$index--;
}
But as you can see, you have to be very careful with the index...
You can use usort function to create own sorting rules
Assuming you just need to reverse an indexed array (not associative or multidimensional) a simple for loop would suffice:
$fruits = ['bananas', 'apples', 'pears'];
for($i = count($fruits)-1; $i >= 0; $i--) {
echo $fruits[$i] . '<br>';
}
If your array is populated through an SQL Query consider reversing the result in MySQL, ie :
SELECT * FROM model_input order by creation_date desc
If you do not have Boolean false values in your array, you could use next code based on internal pointer functions:
$array = ['banana', 'apple', 'pineapple', 'lemon'];
$value = end($array);
while ($value !== false) {
// In case you need a key
$key = key($array);
// Do something you need to
echo $key . ' => ' . $value . "\n";
// Move pointer
$value = prev($array);
}
This solution works for associative arrays with arbitrary keys and do not require altering existing or creating a new one.
<?php
$j=1;
array_reverse($skills_nav);
foreach ( $skills_nav as $skill ) {
$a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
$a .= $skill->name;
$a .= '</a></li>';
echo $a;
echo "\n";
$j++;
}
?>

How to Remove Array Element and Then Re-Index Array?

I have some troubles with an array. I have one array that I want to modify like below. I want to remove element (elements) of it by index and then re-index array. Is it possible?
$foo = array(
'whatever', // [0]
'foo', // [1]
'bar' // [2]
);
$foo2 = array(
'foo', // [0], before [1]
'bar' // [1], before [2]
);
unset($foo[0]); // remove item at index 0
$foo2 = array_values($foo); // 'reindex' array
array_splice($array, 0, 1);
http://php.net/manual/en/function.array-splice.php
You better use array_shift(). That will return the first element of the array, remove it from the array and re-index the array. All in one efficient method.
array_splice($array, array_search(array_value, $array), 1);
2020 Benchmark in PHP 7.4
For these who are not satisfied with current answers, I did a little benchmark script, anyone can run from CLI.
We are going to compare two solutions:
unset() with array_values() VS array_splice().
<?php
echo 'php v' . phpversion() . "\n";
$itemsOne = [];
$itemsTwo = [];
// populate items array with 100k random strings
for ($i = 0; $i < 100000; $i++) {
$itemsOne[] = $itemsTwo[] = sha1(uniqid(true));
}
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
unset($itemsOne[$i]);
$itemsOne = array_values($itemsOne);
}
$end = microtime(true);
echo 'unset & array_values: ' . ($end - $start) . 's' . "\n";
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
array_splice($itemsTwo, $i, 1);
}
$end = microtime(true);
echo 'array_splice: ' . ($end - $start) . 's' . "\n";
As you can see the idea is simple:
Create two arrays both with the same 100k items (randomly generated strings)
Remove 10k first items from first array using unset() and array_values() to reindex
Remove 10k first items from second array using array_splice()
Measure time for both methods
Output of the script above on my Dell Latitude i7-6600U 2.60GHz x 4 and 15.5GiB RAM:
php v7.4.8
unset & array_values: 29.089932918549s
array_splice: 17.94264793396s
Verdict: array_splice is almost twice more performant than unset and array_values.
So: array_splice is the winner!
Unset($array[0]);
Sort($array);
I don't know why this is being downvoted, but if anyone has bothered to try it, you will notice that it works.
Using sort on an array reassigns the keys of the the array. The only drawback is it sorts the values.
Since the keys will obviously be reassigned, even with array_values, it does not matter is the values are being sorted or not.
Try with:
$foo2 = array_slice($foo, 1);
After some time I will just copy all array elements (excluding these unwanted) to new array

which is best array_search or in_array?

I have a large while loop function, every time it gets loaded for check with current URL name.
So I need to know which one is better to check the URL name in large array within the while loop,
in_array() or array_search() function.
If it's a large array and in a loop, neither is "best". Instead use array_flip() on your array, so urls become keys. And use isset() to check for the presence.
There's no real answer here. So I tried it, myself.
$haystack = array
(
'apple',
'banana',
'cherry',
'lemon',
'lime',
'orange',
'potato',
'rutabaga'
);
$haySize = count($haystack);
$loops = isset( $_SERVER['argv'][1] ) ? $_SERVER['argv'][1] : 10000;
// echo 'Loops: ' . $loops . "\n";
$start = microtime(true);
for ($i = 0; $i < $loops; $i++)
{
$needle = $haystack[ $i % $haySize ];
}
$zeroTime = microtime(true) - $start;
// echo sprintf('%0.3f', $zeroTime * 1000) . ' ms : zero time' . "\n";
$start = microtime(true);
for ($i = 0; $i < $loops; $i++)
{
$needle = $haystack[ $i % $haySize ];
$dummy = array_search($needle, $haystack);
}
echo sprintf('%0.3f', (microtime(true) - $start - $zeroTime) * 1000) . ' ms : array_search' . "\n";
$start = microtime(true);
for ($i = 0; $i < $loops; $i++)
{
$needle = $haystack[ $i % $haySize ];
$dummy = in_array($needle, $haystack);
}
echo sprintf('%0.3f', (microtime(true) - $start - $zeroTime) * 1000) . ' ms : in_array' . "\n";
echo sprintf('%0.3f', (microtime(true) - $start) * 1000).' ms : in_array'."\n";
For a typical use case, in_array wins, but the difference is negligible:
22.662 ms : array_search
22.104 ms : in_array
Updated 2014-01-02: added noop loop to "zero the scale". Running PHP 5.4.17 on a new MacBook pro, this is a typical result:
24.462 ms : array_search
24.984 ms : in_array
Based on the documentation of in_array and array_search, I'd think that it mainly depends on what you want to do with the information: if you need the entry, use array_search, if you just want to check if the url exists in the array, in_array should be enough.
it's different function
in_array - return true if find value
array_search - return position if find value
$a = array('a', 'b');
var_dump(in_array('a', $a)); // return true
var_dump(array_search('a', $a)); // return 0
if (array_search('a', $a)) - false
If you're only goal is to check if an URL exists in the array I'd go for in_array. Altough the best way is having keys set so you can just search by array key. That way you save alot of looping.
$searchword = "test";
echo $array[$searchword];
It's up to your array-size.
-If you have a small array(like < 500k 32bit-key),
in_array and array_search give you same performance
isset(array[needle]) make no sense because of flip()
-By big arrays(like > 1m 32bit key)
There are really big difference between in_array and isset(array[needle])
array1=array("a"=>"one","b"=>"two");
if(in_array("one",$array))
{
echo "array exit";
}
else
{
echo " array not exist";
}
echo "</br>";
//example of array_search():
$b1=array("a"=>"one","b"=>"two");
echo array_search("one",$b1);
in_array return true and false value and array_search return key of the array

Categories