zeckdude
zeckdude

Reputation: 16163

How do I remove a specific key in an array using php?

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?

Upvotes: 16

Views: 31179

Answers (5)

mickmackusa
mickmackusa

Reputation: 47883

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.

Upvotes: 10

Hackity Hack
Hackity Hack

Reputation: 31

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

Upvotes: 1

hakre
hakre

Reputation: 197682

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);

Upvotes: 0

Simone
Simone

Reputation: 21262

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);

Upvotes: 11

JJJ
JJJ

Reputation: 33163

Use array_splice().

array_splice( $b, 1, 1 );
// $b == Array ( [0] => 123 [1] => 789 [2] => 123 )

Upvotes: 3

Related Questions