Wie kann ich nach array_filter () die Schlüssel so zurücksetzen, dass sie in numerischer Reihenfolge ab 0 beginnen?

108

Ich habe gerade array_filter verwendet, um Einträge zu entfernen, die nur den Wert '' hatten, und jetzt möchte ich abhängig vom Platzhalter ab 0 bestimmte Transformationen darauf anwenden, aber leider behält es den ursprünglichen Index bei. Ich habe eine Weile gesucht und konnte nichts sehen, vielleicht habe ich nur das Offensichtliche verpasst, aber meine Frage ist ...

Wie kann ich die Indizes des Arrays einfach so zurücksetzen, dass sie bei 0 beginnen und im NEUEN Array in der richtigen Reihenfolge angezeigt werden, anstatt alte Indizes beizubehalten?

jel402
quelle
Mögliches Duplikat von PHP Array_Filter ohne Schlüsselerhaltung
Yep_It's_Me
Sofern Sie nicht absolut sicher sind, dass Ihr Array keine leeren / null-ish / falsey-Werte enthält, muss ich Sie dringend bitten, diese nicht zu verwenden array_filter()- Sie können mehr löschen, als Sie beabsichtigen. Hier ist eine Erklärung mit einer Demo: stackoverflow.com/a/43657056/2943403
mickmackusa

Antworten:

37

Wenn Sie den Array-Filter verwenden, gehen Sie wie folgt vor

$NewArray = array_values(array_filter($OldArray));
user2182143
quelle
3
Oh, die Zeit, die ich verloren habe, um herauszufinden, warum das Ergebnis von json_encode, einem Array, anders ist als das von json_encode, einem array_filtered Array ... vielen Dank ...
Jerther
13

Ich mache mir Sorgen darüber, wie viele Programmierer die array_values(array_filter())Methode unschuldig in ihre Codes kopiert / eingefügt haben - ich frage mich, wie viele Programmierer aufgrund der Gier von array_filter unabsichtlich auf Probleme gestoßen sind. Oder schlimmer noch, wie viele Leute haben nie entdeckt, dass die Funktion zu viele Werte aus dem Array löscht ...

Ich werde eine bessere Alternative für den zweiteiligen Prozess vorstellen, bei dem NULLElemente aus einem Array entfernt und die Schlüssel neu indiziert werden.

Zunächst ist es jedoch äußerst wichtig, dass ich die gierige Natur von array_filter()betone und wie dies Ihr Projekt stillschweigend zum Schraubenschlüssel machen kann. Hier ist ein Array mit gemischten Werten, das das Problem aufdeckt:

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

Nullwerte werden unabhängig von Groß- / Kleinschreibung entfernt.

Aber schauen Sie sich an, was im Array verbleibt, wenn wir array_values ​​() & array_filter () verwenden :

array_values(array_filter($array));

Ausgabearray ($ array):

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

Schauen Sie sich nun an, was Sie mit meiner Methode erhalten, die array_walk () & is_null () verwendet , um ein neues gefiltertes Array zu generieren:

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

Dies kann zum leichteren Lesen / Erklären über mehrere Zeilen geschrieben werden:

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

Ausgabearray ($ filter):

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

Mit meiner Methode erhalten Sie Ihre neu indizierten Schlüssel, alle Nicht-Null-Werte und keinen der Null-Werte. Ein sauberer, tragbarer und zuverlässiger Einzeiler für alle Ihre Anforderungen an die Nullfilterung von Arrays. Hier ist eine Demonstration .



Wenn Sie leere, falsche und null Elemente entfernen möchten (wobei Nullen beibehalten werden), funktionieren diese vier Methoden ebenfalls:

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

oder

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

oder

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

oder

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

Ausgabe:

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

Schließlich können Sie für alle, die die Syntax von Sprachkonstrukten bevorzugen, auch einfach qualifizierende Werte in ein neues Array verschieben, um neue Indizes auszugeben.

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

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

var_export($result);
mickmackusa
quelle
2
Verhalten sich die Dinge nicht genau so, wie Sie es erwarten, wenn Sie schreiben array_values(array_filter($arr, function($el) {return $el !== '';}))? Das scheint der natürliche Weg zu sein, um das zu tun, wonach das OP fragt.
Casey
1
Ja. Mein Punkt ist, dass Entwickler den Drang vermeiden sollten, das Standardverhalten von zu verwenden, es array_filter()sei denn, ihre genaue Kenntnis der Daten erlaubt eine gierige Filterung ohne Nebenwirkungen. (Eine weitere Warnung: empty()verhält sich auf die gleiche Weise und schließt auch ein leeres Array in seine Gier ein.)
mickmackusa
2
Diese Antwort beantwortet eine völlig andere Frage, die in keiner Weise, Form oder Gestalt mit der ursprünglichen zusammenhängt.
AnrDaemon
1
array_filter()verhält sich genau so, wie Sie es erwarten würden, basierend auf den Angaben im Handbuch: php.net/manual/en/function.array-filter.php "Wenn kein Rückruf bereitgestellt wird, sind alle Einträge des Arrays gleich FALSE (siehe Konvertieren in Boolesche Werte) ) wird entfernt. " Und es sollte unter PHP-Programmierern allgemein bekannt sein, dass 0, null, false, '' und '0' alle als false ausgewertet werden, wenn sie zu boolean gezwungen werden.
Madsen
1
Die meisten Leute wissen nicht, was sie erwarten sollen. Sie tun, ich tue, aber viele nicht. Ich habe diese Antwort gepostet, um Leuten zu helfen, die es nicht wissen.
Mickmackusa
12

Verwendung 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
quelle