235

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]

);
daGrevis
  • 21,014
  • 37
  • 100
  • 139

8 Answers8

525
unset($foo[0]); // remove item at index 0
$foo2 = array_values($foo); // 'reindex' array
xzyfer
  • 13,937
  • 5
  • 35
  • 46
  • 4
    This is better than deceze's solution if several items needs to be removed at once - if the indexes of those items are collected beforehand. Once you use array_splice on the first item, you lose the indexes of the rest items. – Jānis Elmeris Jul 05 '13 at 10:00
  • 28
    It may be worth noting that you can unset multiple variables/array indexes in a single unset call `unset($foo[0], $foo[3], $bar[1]);` – ᴍᴀᴛᴛ ʙᴀᴋᴇʀ May 14 '14 at 09:41
51
array_splice($array, 0, 1);

http://php.net/manual/en/function.array-splice.php

deceze
  • 510,633
  • 85
  • 743
  • 889
  • 5
    Beware of using this in a loop because it puts the array indices of the loop and of the actual array out of sync. – Mouagip Jul 06 '15 at 14:07
29

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.

rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
Rene
  • 299
  • 3
  • 2
  • 4
    This is fine when you want to retrieve and then remove the first array element, reindexing the array in the process. Its counterpart function `array_pop()` will retrieve and remove the last array element if you need that. But, neither function can be made to act on an element in the middle of the array. – Derrick Miller Mar 15 '17 at 21:06
  • 2
    While this is orthogonally related, the question is explicitely about *any* element of an array, not just the first. – Félix Adriyel Gagnon-Grenier Jul 17 '18 at 18:10
13
array_splice($array, array_search(array_value, $array), 1);
Eddie C.
  • 918
  • 10
  • 16
user1092222
  • 163
  • 1
  • 4
11

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!

barell
  • 1,470
  • 13
  • 19
  • 1
    A third test would be to unset() all 10k, then run array_values() to re-index one time instead of on every loop. That is ~5% faster than array_splice() for me, using your script. – shinypenguin Feb 09 '23 at 03:16
9
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.

Julius Vainora
  • 47,421
  • 9
  • 90
  • 102
frostymarvelous
  • 2,786
  • 32
  • 43
  • 11
    even if the keys will be reassigned, in the correct answer, the initial order will be kept. – s3v3n Apr 29 '11 at 06:35
  • 2
    "I want to remove element (elements) of it by index and then re-index array. Is it possible?" @s3v3n The OP never asked for maintaining initial order. I simply provided a solution that works and does what is stated. – frostymarvelous Apr 23 '14 at 10:02
  • @s3v3n It is not a grudge. I just wish to know why. Obviously to improve in later answers. I agree that there are better methods, but is there a reason this answer is so bad? Is it performance? etc? Same reason I am on SO, to learn as well as teach. – frostymarvelous Apr 23 '14 at 14:53
  • Under normal circumstances, it is very likely that the programmer will need those values in exactly the same order as the input is. Let's take as an example some rows from the database that should be displayed in a table; or a chat application where the replies should be in the exactly same order. The number of examples can be infinite, the point is that in most cases the order needs to be the same or at least the programmer would expect the same order of the elements in the array. – s3v3n Apr 23 '14 at 18:27
  • OK. The database example just made perfect sense to me. Thanks for taking the time out. – frostymarvelous Apr 23 '14 at 22:46
  • This answer is misleading. This is why it is collecting downvotes. It is doing something that is NOT asked for in the question. The asker does not want the values to be re-ordered. They only want the array to be re-indexed. This answer is incorrect/inappropriate. – mickmackusa Jun 16 '22 at 03:44
5

Try with:

$foo2 = array_slice($foo, 1);
hsz
  • 148,279
  • 62
  • 259
  • 315
0

After some time I will just copy all array elements (excluding these unwanted) to new array