Po funkcji array_filter (), jak mogę zresetować klawisze, aby przechodziły w kolejności numerycznej, zaczynając od 0

108

Właśnie użyłem array_filter, aby usunąć wpisy, które miały tylko wartość „” z tablicy, a teraz chcę zastosować do niej pewne przekształcenia w zależności od symbolu zastępczego zaczynającego się od 0, ale niestety nadal zachowuje oryginalny indeks. Szukałem przez chwilę i nic nie widziałem, może po prostu przegapiłem oczywistość, ale moje pytanie brzmi ...

Jak mogę łatwo zresetować indeksy tablicy tak, aby zaczynały się od 0 i przechodziły w kolejności w NOWEJ tablicy, zamiast zachowywać stare indeksy?

jel402
źródło
Możliwy duplikat php array_filter bez zachowania klucza
Tak_It's_Me
O ile nie jesteś absolutnie pewien, że nie masz żadnych pustych / zerowych / falsey wartości w swojej tablicy, muszę cię zachęcić, abyś nie używał array_filter()- możesz wyczyścić więcej niż zamierzasz. Oto kilka wyjaśnień z demo: stackoverflow.com/a/43657056/2943403
mickmackusa

Odpowiedzi:

37

Jeśli używasz filtru Array, zrób to w następujący sposób

$NewArray = array_values(array_filter($OldArray));
user2182143
źródło
3
Och, straciłem czas, próbując dowiedzieć się, dlaczego wynik json_encode an array jest inny niż wynik json_encode a array_filtered array ... dziękuję TAK DUŻO ...
Jerther
13

Martwię się, ilu programistów niewinnie skopiowało / wkleiło array_values(array_filter())metodę do swoich kodów - zastanawiam się, ilu programistów nieświadomie napotkało problemy z powodu chciwości array_filter. Albo co gorsza, ilu ludzi nigdy nie odkryło, że funkcja usuwa zbyt wiele wartości z tablicy ...

Przedstawię lepszą alternatywę dla dwuczęściowego procesu usuwania NULLelementów z tablicy i ponownego indeksowania kluczy.

Jednak po pierwsze, niezwykle ważne jest, aby podkreślić chciwość array_filter()i sposób, w jaki może to po cichu ćwiczyć Twój projekt. Oto tablica z mieszanymi wartościami, które ujawnią problem:

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

Wartości puste zostaną usunięte bez względu na wielkie / małe litery.

Ale spójrz na to, co pozostaje w tablicy, gdy używamy array_values ​​() i array_filter () :

array_values(array_filter($array));

Tablica wyjściowa (tablica $):

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

Teraz spójrz na to, co dostajesz z moim metoda, która używa array_walk () & is_null () , aby wygenerować nowy przefiltrowaną tablicę:

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

Można to napisać w wielu wierszach, aby ułatwić czytanie / wyjaśnianie:

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

Tablica wyjściowa ($ filter):

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

Dzięki mojej metodzie otrzymujesz ponownie indeksowane klucze, wszystkie wartości inne niż null i żadna z wartości null. Czysty, przenośny, niezawodny jednowarstwowy, spełniający wszystkie potrzeby macierzy w zakresie filtrowania zerowego. Oto demonstracja .



Podobnie, jeśli chcesz usunąć elementy puste, fałszywe i null (zachowując zera), te cztery metody będą działać:

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

lub

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

lub

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

lub

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

Wynik:

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

Wreszcie, dla każdego, kto preferuje składnię konstrukcji językowych, możesz po prostu wypchnąć wartości kwalifikujące do nowej tablicy, aby wydać nowe indeksy.

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

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

var_export($result);
mickmackusa
źródło
2
Czy nic nie będzie zachowywać się dokładnie tak, jak się spodziewamy, jeśli napiszesz array_values(array_filter($arr, function($el) {return $el !== '';}))? Wydaje się, że jest to naturalny sposób robienia tego, o co pyta PO.
Casey,
1
Tak. Chodzi mi o to, że programiści powinni unikać chęci używania domyślnego zachowania, array_filter()chyba że ich dokładna znajomość danych pozwala na zachłanne filtrowanie bez skutków ubocznych. (Kolejna uwaga: empty()zachowuje się w ten sam sposób i zawiera również pustą tablicę w swojej chciwości.)
mickmackusa
2
Ta odpowiedź odpowiada na zupełnie inne pytanie, nie związane w żaden sposób, w żaden sposób, ani w formie, z pierwotnym.
AnrDaemon
1
array_filter()zachowuje się dokładnie tak, jak można by oczekiwać na podstawie tego, co jest napisane w podręczniku: php.net/manual/en/function.array-filter.php "Jeśli nie podano wywołania zwrotnego, wszystkie wpisy tablicy są równe FALSE (zobacz konwersję na wartość logiczną ) będzie usunięty." Programiści PHP powinni mieć powszechną wiedzę, że 0, null, false, '' i '0' wszystkie przeliczane są na false, gdy są wymuszone na boolean.
madsen
1
Rzecz w tym, że większość ludzi nie wie, czego się spodziewać. Ty tak, ja, ale wielu nie. Opublikowałem tę odpowiedź, aby pomóc ludziom, którzy nie wiedzą.
mickmackusa
12

Zastosowanie 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
Ed Mazur
źródło