Після array_filter (), як я можу скинути клавіші для переходу в цифровому порядку, починаючи з 0


108

Я просто використав array_filter для видалення записів, які мали лише значення '' з масиву, і тепер я хочу застосувати до нього певні перетворення залежно від заповнювача, починаючи з 0, але, на жаль, він все ще зберігає початковий індекс. Я деякий час дивився і нічого не бачив, можливо, я просто пропустив очевидне, але моє запитання ...

Як я можу легко скинути індекси масиву, які починаються з 0, і перейти до порядку в новому масиві, а не зберегти старі індекси?



Якщо ви абсолютно не впевнені, що у вашому масиві немає жодних значень порожнього / нуля-ish / falsey, я повинен закликати вас не використовувати array_filter()- ви можете очистити більше, ніж ви плануєте. Ось яке - то пояснення з демонстрацією: stackoverflow.com/a/43657056/2943403
mickmackusa

Відповіді:


223

Якщо ви зателефонуєте array_valuesна свій масив, він буде перевстановлений з нуля.


Посилання більше не працює, замість цього використовуйте php.net/manual/en/function.array-values.php . Я не можу його оновити, оскільки мені потрібно змінити принаймні 6 символів.
Расмус Хансен

37

Якщо ви використовуєте фільтр масиву, зробіть це наступним чином

$NewArray = array_values(array_filter($OldArray));

3
О час, який я втратив, намагаючись з'ясувати, чому результат масиву json_encode відрізняється від результату json_encode масиву_фільтрованого масиву ... дякую
ТАКІ МНОГО

13

Я хвилююся про те, скільки програмістів невинно копіювали / вставляли array_values(array_filter())метод у свої коди - мені цікаво, скільки програмістів мимоволі зіткнулися з проблемами через жадібність array_filter. Або ще гірше, скільки людей ніколи не виявили, що функція очищає занадто багато значень з масиву ...

Я представлю кращу альтернативу двоскладовому процесу віддирання NULLелементів з масиву та повторної індексації ключів.

Однак, по-перше, надзвичайно важливо, щоб я підкреслив жадібну природу, array_filter()і як це мовчки мавповувати ваш проект. Ось масив із змішаними значеннями в ньому, який викриє проблему:

$array=['foo',NULL,'bar',0,false,null,'0',''];

Нульові значення будуть видалені незалежно від великих / малих літер.

Але подивіться, що залишається у масиві, коли ми використовуємо array_values ​​() & array_filter () :

array_values(array_filter($array));

Вихідний масив ($ масив):

array (
  0 => 'foo',
  1 => 'bar'
)
// All empty, zero-ish, falsey values were removed too!!!

Тепер подивіться, що ви отримуєте з мого методу, який використовує array_walk () & is_null () для створення нового відфільтрованого масиву:

array_walk($array,function($v)use(&$filtered){if(!is_null($v)){$filtered[]=$v;}});

Це можна записати через кілька рядків для легшого читання / пояснення:

array_walk(                      // iterate each element of an input array
    $array,                      // this is the input array
    function($v)use(&$filtered){ // $v is each value, $filter (output) is declared/modifiable
        if(!is_null($v)){        // this literally checks for null values
            $filtered[]=$v;      // value is pushed into output with new indexes
        }
    }
);

Вихідний масив ($ filter):

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => false,
  4 => '0',
  5 => '',
)

За допомогою мого методу ви отримуєте свої реіндексовані ключі, усі ненульові значення та жодне з нульових значень. Чистий, портативний, надійний одноколісний вхід для всіх ваших потреб з фільтрування нуля. Ось демонстрація .



Аналогічно, якщо ви хочете видалити порожні, помилкові та нульові елементи (збереження нулів), ці чотири методи спрацюють:

var_export(array_values(array_diff($array,[''])));

або

var_export(array_values(array_diff($array,[null])));

або

var_export(array_values(array_diff($array,[false])));

або

var_export(array_values(array_filter($array,'strlen')));

Вихід:

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => '0',
)

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

$array=['foo', NULL, 'bar', 0, false, null, '0', ''];

$result = [];
foreach ($array as $value) {
    if (strlen($value)) {
        $result[] = $value;
    }
}

var_export($result);

2
Чи не будуть справи вестись точно очікуваним чином, якщо ви пишете array_values(array_filter($arr, function($el) {return $el !== '';}))? Це здається природним способом зробити те, про що просить ОП.
Кейсі

1
Так. Моя думка, що розробники повинні уникати спонукань використовувати поведінку за замовчуванням, array_filter()якщо тільки їх інтимне знання даних не дозволяє жадібної фільтрації без побічних ефектів. (Подальша обережність: empty()веде себе таким же чином, а також включає порожній масив у свою
жадібність

2
Ця відповідь відповідає зовсім іншим запитанням, не пов'язаним з оригінальним жодним чином, формою чи формою.
AnrDaemon

1
array_filter()поводиться точно так, як ви очікували, виходячи з того, що йдеться в посібнику: php.net/manual/en/function.array-filter.php "Якщо зворотний виклик не надається, усі записи масиву рівні FALSE (див. перетворення на булевий" ) буде видалено. " І серед програмістів PHP повинно бути загальновідомо, що 0, null, false, '' і '0' оцінюються як false, коли примушуються до булевих.
madsen

1
Річ у тому, що більшість людей не знають, чого очікувати. Ви робите, я так, але багато хто ні. Я опублікував цю відповідь, щоб допомогти людям, які не знають.
mickmackusa

12

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

<?php

$array = array('foo', 'bar', 'baz');
$array = array_filter($array, function ($var) {
    return $var !== 'bar';
});

print_r($array); // indexes 0 and 2
print_r(array_values($array)); // indexes 0 and 1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.