Обновіть ключі масиву після скидання елементів


183

У мене є масив:

$array = array(1,2,3,4,5);

Якби я скидав вміст масиву, вони виглядали б так:

array(5) {
  [0] => int(1)
  [1] => int(2)
  [2] => int(3)
  [3] => int(4)
  [4] => int(5)
}

Коли я перебираю і знімаю певні клавіші, індекс стає все підключеним.

foreach($array as $i => $info)
{
  if($info == 1 || $info == 2)
  {
    unset($array[$i]);
  }
}

Згодом, якби я зробив ще один дамп, він виглядав би так:

array(3) {
  [2] => int(3)
  [3] => int(4)
  [4] => int(5)
}

Чи є правильний спосіб скинути масив, щоб його елементи знову базувалися на нулі ??

array(3) {
  [0] => int(3)
  [1] => int(4)
  [2] => int(5)
}

Відповіді:


411

Спробуйте це:

$array = array_values($array);

Використання array_values ​​()


6
+1. Зауважу, що в посібнику прямо не вказано, що замовлення буде підтримуватися, але я не можу зрозуміти, чому цього не було б.
Гонки легкості по орбіті

16
Так, замовлення безумовно підтримується. Була б прикрою функцією, якби вона переупорядкувала її! :)
webbiedave

1
@webbiedave вибачте, але це неправда. Це насправді переробляє мій масив. Дуже дуже дивно.
FooBar

4
завжди йдіть на прості стислі рішення :)
Брюс Лім

1
Хоча це просте рішення, коли масив уже пронумерований, він не працює, коли ключ встановлений як текст, як би це було частиною форми HTML. Якщо ви покладаєтесь на унікальні ключові значення для ідентифікації виводу з форми, один із наведених нижче методів працює краще.

17

Отримали ще один цікавий метод:

$array = array('a', 'b', 'c', 'd'); 
unset($array[2]); 

$array = array_merge($array); 

Тепер клавіші $ масиву скидаються.


13

Використовуйте, array_spliceа не unset:

$array = array(1,2,3,4,5);
foreach($array as $i => $info)
{
  if($info == 1 || $info == 2)
  {
    array_splice($array, $i, 1);
  }
}

print_r($array);

Робочий зразок тут .


7
Це не працює. сплайс був би дивним, але ви не можете використовувати його всередині циклу for / foreach, оскільки він переставляє індекс кожного разу, коли ви викликаєте його, тому індекс циклу foreach не вказує на наступний елемент, а на елемент із цим положенням на переставленому масиві. Ви можете побачити в своєму прикладі, що ви видаляєте значення "3" і залишаєте значення "2", коли вам слід видалити лише значення "1" і "2"
NotGaeL

1
@elcodedocle Тоді не використовуйте foreachцикл. Використовуйте стандартний i Loopта просто скиньте i після сплайсу. Також Working sample here.не працює.
SpYk3HH

Пошкоджене посилання, ви могли б це виправити?
Мішель Ейрес

5

Просто добавка.

Я знаю, що це старе , але я хотів додати рішення, яке не бачу, що я придумав сам. Знайшов це питання під час полювання на інше рішення і просто подумав: "Ну, поки я тут".

Перш за все, відповідь Ніла добре і чудово використовувати після запуску циклу, проте я вважаю за краще виконати всю роботу відразу. Звичайно, в моєму конкретному випадку мені довелося зробити більше роботи, ніж цей простий приклад, але метод все-таки застосовується. Я бачив, де пара інших пропонувала foreachпетлі, однак це все одно залишає вас після роботи через природу звіра. Зазвичай я пропоную простіші речі, як foreach, однак, у цьому випадку найкраще запам’ятати добру старомодну for loopлогіку. Просто використовуйте i! Щоб підтримувати відповідний індекс, просто відніміть iпісля кожного видалення елемента масиву.

Ось мій простий, робочий приклад:

$array = array(1,2,3,4,5);

for ($i = 0; $i < count($array); $i++) {
    if($array[$i] == 1 || $array[$i] == 2) {
        array_splice($array, $i, 1);
        $i--;
    }
}

Виведе:

array(3) {
    [0]=> int(3)
    [1]=> int(4)
    [2]=> int(5)
}

Це може мати багато простих реалізацій. Наприклад, мій точний випадок вимагає зберігання останнього елемента в масиві на основі багатовимірних значень. Я покажу, що я маю на увазі:

$files = array(
    array(
        'name' => 'example.zip',
        'size' => '100000000',
        'type' => 'application/x-zip-compressed',
        'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
        'deleteUrl' => 'server/php/?file=example.zip',
        'deleteType' => 'DELETE'
    ),
    array(
        'name' => 'example.zip',
        'size' => '10726556',
        'type' => 'application/x-zip-compressed',
        'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
        'deleteUrl' => 'server/php/?file=example.zip',
        'deleteType' => 'DELETE'
    ),
    array(
        'name' => 'example.zip',
        'size' => '110726556',
        'type' => 'application/x-zip-compressed',
        'deleteUrl' => 'server/php/?file=example.zip',
        'deleteType' => 'DELETE'
    ),
    array(
        'name' => 'example2.zip',
        'size' => '12356556',
        'type' => 'application/x-zip-compressed',
        'url' => '28188b90db990f5c5f75eb960a643b96/example2.zip',
        'deleteUrl' => 'server/php/?file=example2.zip',
        'deleteType' => 'DELETE'
    )
);

for ($i = 0; $i < count($files); $i++) {
    if ($i > 0) {
        if (is_array($files[$i-1])) {
            if (!key_exists('name', array_diff($files[$i], $files[$i-1]))) {
                if (!key_exists('url', $files[$i]) && key_exists('url', $files[$i-1])) $files[$i]['url'] = $files[$i-1]['url'];
                $i--;
                array_splice($files, $i, 1);
            }
        }
    }
}

Виведе:

array(1) {
    [0]=> array(6) {
            ["name"]=> string(11) "example.zip"
            ["size"]=> string(9) "110726556"
            ["type"]=> string(28) "application/x-zip-compressed"
            ["deleteUrl"]=> string(28) "server/php/?file=example.zip"
            ["deleteType"]=> string(6) "DELETE"
            ["url"]=> string(44) "28188b90db990f5c5f75eb960a643b96/example.zip"
        }
    [1]=> array(6) {
            ["name"]=> string(11) "example2.zip"
            ["size"]=> string(9) "12356556"
            ["type"]=> string(28) "application/x-zip-compressed"
            ["deleteUrl"]=> string(28) "server/php/?file=example2.zip"
            ["deleteType"]=> string(6) "DELETE"
            ["url"]=> string(45) "28188b90db990f5c5f75eb960a643b96/example2.zip"
        }
}

Як бачите, я маніпулюю $ i перед сплайсом, оскільки я прагну видалити попередній, а не даний елемент.


1

Пізня відповідь, але після PHP 5.3 може бути так;

$array = array(1, 2, 3, 4, 5);
$array = array_values(array_filter($array, function($v) {
    return !($v == 1 || $v == 2);
}));
print_r($array);

1

Або ви можете зробити власну функцію, яка передає масив за посиланням.

function array_unset($unsets, &$array) {
  foreach ($array as $key => $value) {
    foreach ($unsets as $unset) {
      if ($value == $unset) {
        unset($array[$key]);
        break;
      }
    }
  }
  $array = array_values($array);
}

Тож все, що вам потрібно зробити, це ...

$unsets = array(1,2);
array_unset($unsets, $array);

... і тепер ваша $arrayбез значень, які ви помістили, $unsetsі ключі скидаються


1

100% працює для мене! Після скидання елементів масиву ви можете використовувати це для повторної індексації масиву

$result=array_combine(range(1, count($your_array)), array_values($your_array));

0

Я використовую $arr = array_merge($arr); для відновлення масиву. Простий і прямолінійний.


-2

У моїй ситуації мені потрібно було зберегти унікальні ключі зі значеннями масиву, тому я просто використав другий масив:

$arr1 = array("alpha"=>"bravo","charlie"=>"delta","echo"=>"foxtrot");
unset($arr1);

$arr2 = array();
foreach($arr1 as $key=>$value) $arr2[$key] = $value;
$arr1 = $arr2
unset($arr2);

1) Ви, unset($arr1)який зробить його НЕ доступним для повторення у своєму циклі. 2) Ви пропускаєте крапку з комою у другому до останнього рядка. Цей фрагмент коду не запускається.
Rockin4Life33
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.