У меня есть массив, который может содержать числовые или ассоциативные ключи или обоих:
$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)
удалил бы элемент "панели", а не "d" элемент).
Это должно привести к переиндексации массива при сохранении ключей строк:
$x = array_merge($x);
Я придумал это - хотя не уверен, что это лучшее:
// 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.
Есть несколько вещей, которые я упустил, просто для краткости. Например, вы бы проверили, ассоциативен ли массив, а также является ли удаляемый ключ строкой или нет, прежде чем использовать приведенный выше код
.Попробуйте array_diff(), он может неправильно упорядочить новый массив, хотя если это не так, то в функции удаления необходимо выполнить
DC
итерацию.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;
}
DC
Не думаю, что есть элегантное решение этой проблемы, наверное, нужно зацикливаться на массив и переупорядочивать ключи самостоятельно.