Wie entferne ich ein Array-Element in einer foreach-Schleife?

127

Ich möchte ein Array mit durchlaufen foreach, um zu überprüfen, ob ein Wert vorhanden ist. Wenn der Wert vorhanden ist, möchte ich das Element löschen, das ihn enthält.

Ich habe folgenden Code:

foreach($display_related_tags as $tag_name) {
    if($tag_name == $found_tag['name']) {
        // Delete element
    }
}

Ich weiß nicht, wie ich das Element löschen soll, sobald der Wert gefunden wurde. Wie lösche ich es?

Ich muss foreachfür dieses Problem verwenden. Es gibt wahrscheinlich Alternativen zu foreach, und Sie können sie gerne teilen.

Ajsie
quelle

Antworten:

219

Wenn Sie auch den Schlüssel erhalten, können Sie diesen Eintrag folgendermaßen löschen:

foreach ($display_related_tags as $key => $tag_name) {
    if($tag_name == $found_tag['name']) {
        unset($display_related_tags[$key]);
    }
}
Gumbo
quelle
3
Einige zusätzliche Informationen zur Optimierung mithilfe von $key => &$tag_name stackoverflow.com/a/2008893/922522
Justin
5
Beachten Sie, dass indizierte Arrays mit nicht gesetzten Elementen nach a als Objekte anstelle von Arrays dargestellt werden können json_encode(). Sie können dies mit $display_related_tags = array_values ($display_related_tags);nach der foreachSchleife lösen .
Márton Tamás
Beachten Sie, dass der Trick hier darin besteht, der foreach-Schleife einen Wert hinzuzufügen ;-)
Mr Washington,
5
Bitte siehe @Neils Antwort. Sie werden auf unerwartete Fehler stoßen, insbesondere wenn Sie mit Array of stdClasses arbeiten. Magst du unerwartetes Verhalten? Ich nicht.
happy_marmoset
@happy_marmoset Neils Antwort hilft nicht. Snippet $projects = array_filter($projects, function ($project) { return count($project->roles) > 0; });konvertiert das Ergebnis in ein Objekt.
Paritosh
36

Eine bessere Lösung ist die Verwendung der array_filterFunktion:

$display_related_tags =
    array_filter($display_related_tags, function($e) use($found_tag){
        return $e != $found_tag['name'];
    });

Wie die PHP- Dokumentation lautet:

Da foreach auf den internen Array-Zeiger in PHP 5 angewiesen ist, kann das Ändern innerhalb der Schleife zu unerwartetem Verhalten führen.

In PHP 7 verwendet foreach nicht den internen Array-Zeiger.

Neils
quelle
Beachten Sie, dass der dritte Parameter ARRAY_FILTER_USE_KEY sein sollte, um den Schlüssel hier als $ e zu übergeben.
Namezero
@namezero OK warum ist das hier wichtig?
AbraCadaver
@AbraCadaver Aus der Dokumentation ( php.net/manual/en/function.array-filter.php ): ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value ARRAY_FILTER_USE_BOTH - pass both value and key as arguments to callback instead of the value Default is 0 which will pass value as the only argument to callback instead. Das heißt, das erneute Lesen der Antwort in diesem Fall wäre natürlich nicht wichtig, wie Sie behaupten.
Namezero
Wichtig Wenn Sie daran interessiert sind, das Array als geordnetes Array beizubehalten, müssen Sie danach aufrufen display_related_tags = array_values(display_related_tags);.
Guyaloni
9
foreach($display_related_tags as $key => $tag_name)
{
    if($tag_name == $found_tag['name'])
        unset($display_related_tags[$key];
}
Steve H.
quelle
3
'Verknüpfung aufheben' hebt die Verknüpfung von Dateien auf, es hat nichts mit Variablen oder insbesondere Arrays zu tun. Vielleicht meinst du "nicht gesetzt"?
Amn
6

Anstatt eine foreach () - Schleife für das Array auszuführen, wäre es schneller, array_search () zu verwenden, um den richtigen Schlüssel zu finden. Bei kleinen Arrays würde ich foreach verwenden, um die Lesbarkeit zu verbessern. Bei größeren Arrays oder häufig ausgeführtem Code sollte dies jedoch etwas optimaler sein:

$result=array_search($unwantedValue,$array,true);
if($result !== false) {
  unset($array[$result]);   
}

Der strikte Vergleichsoperator! == wird benötigt, da array_search () 0 als Index für den $ unerwünschten Wert zurückgeben kann.

Im obigen Beispiel wird auch nur der erste Wert $ unwantedValue entfernt. Wenn der $ unwantedValue mehr als einmal im $ -Array auftreten kann, sollten Sie array_keys () verwenden, um alle zu finden:

$result=array_keys($array,$unwantedValue,true)
foreach($result as $key) {
  unset($array[$key]);
}

Weitere Informationen finden Sie unter http://php.net/manual/en/function.array-search.php .

PiotrN
quelle
0

Wenn Sie ein Szenario haben, in dem Sie mehr als einen Wert aus dem foreach-Array entfernen müssen, müssen Sie in diesem Fall jeweils einen Wert als Referenz übergeben: Ich versuche, dieses Szenario zu erklären:

foreach ($manSkuQty as $man_sku => &$man_qty) {

               foreach ($manufacturerSkus as $key1 => $val1) {

  // some processing here and unset first loops entries                     
 //  here dont include again for next iterations
                           if(some condition)
                            unset($manSkuQty[$key1]);

                        }
               }
}

In der zweiten Schleife möchten Sie die Einträge für die ersten Schleifen deaktivieren. Sie werden aus Leistungsgründen nicht erneut in der Iteration angezeigt oder dann auch nicht aus dem Speicher entfernt, da sie im Speicher vorhanden sind und in Iterationen angezeigt werden.

Hassan Ali Shahzad
quelle
0

Es gibt bereits Antworten, die Aufschluss darüber geben, wie das Deaktivieren erfolgen kann. Anstatt Code in all Ihren Klassen zu wiederholen, funktionieren Sie wie folgt und verwenden Sie ihn bei Bedarf im Code. In der Geschäftslogik möchten Sie manchmal einige Eigenschaften nicht verfügbar machen. Bitte sehen Sie unten einen Liner-Aufruf zum Entfernen

public static function removeKeysFromAssociativeArray($associativeArray, $keysToUnset)
{
    if (empty($associativeArray) || empty($keysToUnset))
        return array();

    foreach ($associativeArray as $key => $arr) {
        if (!is_array($arr)) {
            continue;
        }

        foreach ($keysToUnset as $keyToUnset) {
            if (array_key_exists($keyToUnset, $arr)) {
                unset($arr[$keyToUnset]);
            }
        }
        $associativeArray[$key] = $arr;
    }
    return $associativeArray;
}

Rufen Sie an wie:

removeKeysFromAssociativeArray($arrValues, $keysToRemove);
Somnath Muluk
quelle
-1

Wie bereits erwähnt, möchten Sie einen Foreach mit dem Schlüssel durchführen und die Verwendung des Schlüssels deaktivieren. Beachten Sie jedoch, dass das Mutieren eines Arrays während der Iteration im Allgemeinen eine schlechte Idee ist, obwohl ich mir bezüglich der PHP-Regeln nicht sicher bin spontan.

Ciarán Walsh
quelle
2
Ein PHP-Foreach wird unabhängig davon auf dem gesamten Array ausgeführt. Testen Sie das Deaktivieren eines Werts, der als nächstes in der Iteration angezeigt wird. Der Offset wird iteriert, der Wert ist jedoch null.
Kevin Peno
Wenn Sie ein Array während der Iteration nicht mutieren, wie mutieren Sie dann überhaupt ein Array? Kann Mittelwert foreachoder forKonstruktionen anstelle von Iteration im Allgemeinen sein?
Gherman
Dies ist eher ein Kommentar zu einer anderen Antwort als eine Antwort an und für sich.
Unheimlicher Bart