Перебазировать ключи массива после сброса элементов

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)
}
TuK
источник

Ответы:

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

Теперь ключи $ 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
Это не работает. splice был бы замечательным, но вы не можете использовать его внутри цикла 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 перед соединением, поскольку я пытаюсь удалить предыдущий, а не текущий элемент.

SpYk3HH
источник
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);
K-Gun
источник
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и ключи сброшены

upful
источник
1

100% работает на меня! После сброса элементов в массиве вы можете использовать это для переиндексации массива

$result=array_combine(range(1, count($your_array)), array_values($your_array));
Атта Ур Рехман
источник
0

Я использую, $arr = array_merge($arr); чтобы перебазировать массив. Просто и понятно.

Rockin4Life33
источник
-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