Reputation: 16163
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
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.
unset()
then array_values()
unset($b[1]);
$b = array_value($b);
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.unset()
is not particularly handy for removing elements using a dynamic whitelist/blacklist of keys.array_splice()
array_splice($b, 1, 1);
// (input array, starting position, number of elements to remove)
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.array_filter()
nested in array_values()
array_values(
array_filter(
$b,
function($k) {
return $k != 1;
},
ARRAY_FILTER_USE_KEY
)
)
in_array()
call with a whitelist/blacklist of keys in the custom function.use()
.array_diff_key()
nested in array_values()
array_values(
array_diff_key(
$b,
[1 => '']
)
);
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.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.Upvotes: 10
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
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
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
Reputation: 33163
Use array_splice()
.
array_splice( $b, 1, 1 );
// $b == Array ( [0] => 123 [1] => 789 [2] => 123 )
Upvotes: 3