Как удалить значения из массива при перенумерации числовых ключей

У меня есть массив, который может содержать числовые или ассоциативные ключи, или оба:

$x = array('a', 'b', 'c', 'foo' => 'bar', 'd', 'e');
print_r($x);
/*(
    [0] => a
    [1] => b
    [2] => c
    [foo] => bar
    [3] => d
    [4] => e
)*/

Я хочу иметь возможность удалить элемент из массива, перенумеровав неассоциативные ключи, чтобы они оставались последовательными:

$x = remove($x, "c");
print_r($x);
/* desired output:
(
    [0] => a
    [1] => b
    [foo] => bar
    [2] => d
    [3] => e
)*/

Поиск нужного элемента для удаления не проблема, это ключи, которые являются проблемой. unset не перенумеровывает ключи, и array_splice работает со смещением, а не с ключом (т.е. взять $x из первого примера, array_splice($x, 3, 1) удалит элемент "bar", а не элемент "d").

5 ответов

Решение

Это должно переиндексировать массив при сохранении строковых ключей:

$x = array_merge($x);

Вы можете исправить с помощью следующего решения ELEGANT:

Например:



$ массив = массив (1 => 'A',
    2 => 'B',
    3 => 'C');

снята с охраны ($ массив [2]);

/ * $ массив теперь:
Array (
    1 => 'A',
    3 => 'C');
Как видите, индекс "2" отсутствует в массиве. 
* /

// РЕШЕНИЕ:
$array = array_values ​​($ array);

/ * $ массив теперь:
Array (
    0 => 'A',
    1 => 'C');
Как видите, индекс начинается с нуля. 
*/?>

Попробуйте array_diff(), он может неправильно упорядочить новый массив, хотя в противном случае должно работать следующее

Вам нужно будет перебрать его в функции удаления.

function remove($x,$r){
 $c = 0;
 $a = array();
 foreach ($x as $k=>$v){
   if ($v != $r) {
     if (is_int($k)) {
       $a[$c] = $v;
       $c++;
     }
     else {
       $a[$k] = $v;
     }
   } 
 }
 return $a;
}

ОКРУГ КОЛУМБИЯ

Я придумал это - хотя я не уверен, что это лучшее:

// given: $arr is the array
//        $item is the item to remove

$key = array_search($item, $arr);  // the key we need to remove
$arrKeys = array_keys($arr);
$keyPos = array_search($key, $arrKeys); // the offset of the item in the array

unset($arr[$key]);
array_splice($arrKeys, $keyPos, 1);

for ($i = $keyPos; $i < count($arrKeys); ++$i) {
    if (is_int($arrKeys[$i])) --$arrKeys[$i]; // shift numeric keys back one
}
$arr = array_combine($arrKeys, $arr);  // recombine the keys and values.

Есть несколько вещей, которые я пропустил, просто ради краткости. Например, вы должны проверить, является ли массив ассоциативным, а также, является ли удаляемый ключ строкой или нет, прежде чем использовать приведенный выше код.

Я не думаю, что есть изящное решение этой проблемы, вам, вероятно, нужно зациклить массив и переупорядочить ключи самостоятельно.

Другие вопросы по тегам