So überprüfen Sie, ob mehrere Array-Schlüssel vorhanden sind

Lesezeit: 7 Minuten

Benutzer-Avatar
Ryan

Ich habe eine Vielzahl von Arrays, die entweder enthalten

story & message

oder nur

story

Wie würde ich überprüfen, ob ein Array sowohl eine Geschichte als auch eine Nachricht enthält? array_key_exists() sucht nur nach diesem einzelnen Schlüssel im Array.

Gibt es eine Möglichkeit, dies zu tun?

  • Wenn “Geschichte” in beiden Fällen vorhanden ist, klingt es so, als müssten Sie wirklich nur nach “Nachricht” suchen.

    – Wyzard

    1. November 2012 um 1:03 Uhr

  • Verwenden array_intersect_key() Vergleichen Sie ein Array der Schlüssel, die Sie überprüfen möchten, mit dem Array, das Sie überprüfen. Wenn die Länge der Ausgabe dieselbe ist wie das Array der zu prüfenden Schlüssel, sind sie alle vorhanden.

    – Michael Berkowski

    1. November 2012 um 1:04 Uhr

  • Wyzard, ich habe andere Arrays, die eine Nachricht enthalten, aber keine Geschichte, aber diese haben andere Schlüssel, die ein Array mit entweder Geschichte oder Geschichte und Nachricht nur enthalten würde. Vielen Dank

    – Ryan

    1. November 2012 um 1:07 Uhr

  • Verwechseln Sie hier Schlüssel und Werte? Ist das Array wie formatiert ["story & message" => "value"] oder ist es eher so ["story & message"]

    – GordonM

    25. Januar 2017 um 9:34 Uhr

Benutzer-Avatar
Erfan

Hier ist eine Lösung, die skalierbar ist, auch wenn Sie nach einer großen Anzahl von Schlüsseln suchen möchten:

<?php

// The values in this arrays contains the names of the indexes (keys) 
// that should exist in the data array
$required = array('key1', 'key2', 'key3');

$data = array(
    'key1' => 10,
    'key2' => 20,
    'key3' => 30,
    'key4' => 40,
);

if (count(array_intersect_key(array_flip($required), $data)) === count($required)) {
    // All required keys exist!
}

  • In der Tat eine clevere Lösung, aber sie ist wirklich langsamer (etwa 50% langsamer auf meiner Box) als eine einfache : “` $ok = true; foreach( $required as $field ) { if( !array_key_exists( $field, $data ) ) $ok = false; }

    – Osch

    24. Dezember 2013 um 17:29 Uhr


  • Dies sollte mit doppelten Werten im Array funktionieren return empty(array_intersect($keys, array_keys($array)));

    – Mei Gwilym

    3. November 2016 um 15:30 Uhr

  • Für diejenigen, die nur prüfen möchten, ob irgendein der Schlüssel vorhanden sind, verwenden > 0 Anstatt von === count($required).

    – CPHPython

    17. August 2018 um 10:23 Uhr

Benutzer-Avatar
Alex

Wenn Sie nur 2 Schlüssel überprüfen müssen (wie in der ursprünglichen Frage), ist es wahrscheinlich einfach genug, einfach anzurufen array_key_exists() zweimal, um zu prüfen, ob die Schlüssel vorhanden sind.

if (array_key_exists("story", $arr) && array_key_exists("message", $arr)) {
    // Both keys exist.
}

Dies lässt sich jedoch offensichtlich nicht gut auf viele Tasten skalieren. In dieser Situation würde eine benutzerdefinierte Funktion helfen.

function array_keys_exists(array $keys, array $arr) {
   return !array_diff_key(array_flip($keys), $arr);
}

  • @alex das einzige Problem ist, dass wenn $keys enthält ein Element, das nicht drin ist $arr und ein anderer, der darin ist, !array_diff_key gibt leer zurück => false (3v4l-Beispiel)…

    – CPHPython

    17. August 2018 um 10:10 Uhr

  • Ich denke, dies kann durch Verwendung besser lesbar gemacht werden !array_diff($keys, array_keys($array)); weil es etwas weniger kognitive Belastung gibt, diese zu erarbeiten array_flips.

    – moopet

    29. März 2019 um 12:05 Uhr

Benutzer-Avatar
Markus Fuchs

Überraschenderweise array_keys_exist gibt es nicht?! In der Zwischenzeit bleibt etwas Platz, um einen einzeiligen Ausdruck für diese gemeinsame Aufgabe zu finden. Ich denke an ein Shell-Skript oder ein anderes kleines Programm.

Hinweis: Jede der folgenden Lösungen verwendet kurz […] Array-Deklarationssyntax verfügbar in PHP 5.4+

array_diff + array_keys

if (0 === count(array_diff(['story', 'message', '…'], array_keys($source)))) {
  // all keys found
} else {
  // not all
}

(Hutspitze an Kim Stacks)

Dieser Ansatz ist der kürzeste, den ich gefunden habe. array_diff() gibt ein Array von Elementen zurück, die in Argument 1 vorhanden sind nicht vorhanden in argument2. Daher zeigt ein leeres Array an, dass alle Schlüssel gefunden wurden. In PHP 5.5 könnte man vereinfachen 0 === count(…) einfach sein empty(…).

array_reduce + ungesetzt

if (0 === count(array_reduce(array_keys($source), 
    function($in, $key){ unset($in[array_search($key, $in)]); return $in; }, 
    ['story', 'message', '…'])))
{
  // all keys found
} else {
  // not all
}

Schwerer zu lesen, leicht zu ändern. array_reduce() verwendet einen Rückruf, um über ein Array zu iterieren, um zu einem Wert zu gelangen. Indem wir die Schlüssel füttern, interessieren wir uns für die $initial Wert von $in und dann die in der Quelle gefundenen Schlüssel entfernen, können wir davon ausgehen, dass sie mit 0 Elementen enden, wenn alle Schlüssel gefunden wurden.

Die Konstruktion ist leicht zu ändern, da die Schlüssel, an denen wir interessiert sind, gut in die untere Zeile passen.

array_filter & in_array

if (2 === count(array_filter(array_keys($source), function($key) { 
        return in_array($key, ['story', 'message']); }
    )))
{
  // all keys found
} else {
  // not all
}

Einfacher zu schreiben als die array_reduce Lösung, aber etwas schwieriger zu bearbeiten. array_filter ist auch ein iterativer Callback, mit dem Sie ein gefiltertes Array erstellen können, indem Sie im Callback true (Element in neues Array kopieren) oder false (nicht kopieren) zurückgeben. Das Gotchya ist, dass Sie sich ändern müssen 2 auf die Anzahl der Artikel, die Sie erwarten.

Dies kann haltbarer gemacht werden, grenzt aber an absurde Lesbarkeit:

$find = ['story', 'message'];
if (count($find) === count(array_filter(array_keys($source), function($key) use ($find) { return in_array($key, $find); })))
{
  // all keys found
} else {
  // not all
}

  • der Unterschied wird für kleine Sätze vernachlässigbar sein. Wenn Sie eine Bibliothek/ein Framework schreiben, das große Datenmengen verarbeitet, sollten Sie wahrscheinlich die Leistung jeder Einheit testen, um Engpässe zu finden, anstatt sie vorzeitig zu optimieren.

    – Markus Fuchs

    25. November 2014 um 19:17 Uhr

Benutzer-Avatar
Vasily

Noch eine mögliche Lösung:

if (!array_diff(['story', 'message'], array_keys($array))) {
    // OK: all the keys are in $array
} else {
   // FAIL: some keys are not
}

Benutzer-Avatar
Peter Zibulka

Die einfachste Methode scheint mir folgende zu sein:

$required = array('a','b','c','d');

$values = array(
    'a' => '1',
    'b' => '2'
);

$missing = array_diff_key(array_flip($required), $values);

Drucke:

Array(
    [c] => 2
    [d] => 3
)

Dadurch kann auch überprüft werden, welche Schlüssel genau fehlen. Dies kann für die Fehlerbehandlung nützlich sein.

Benutzer-Avatar
Ihr gesunder Menschenverstand

Die obigen Lösungen sind clever, aber unnötig langsam. Eine einfache foreach-Schleife über ein paar Tasten ist viel schneller.

function array_keys_exist($keys, $array){
    foreach($keys as $key){
        if(!array_key_exists($key, $array)) {
            return false;
        }
    }
    return true;
}

Benutzer-Avatar
Sven

Wenn Sie so etwas haben:

$stuff = array();
$stuff[0] = array('story' => 'A story', 'message' => 'in a bottle');
$stuff[1] = array('story' => 'Foo');

Du könntest einfach count():

foreach ($stuff as $value) {
  if (count($value) == 2) {
    // story and message
  } else {
    // only story
  }
}

Dies funktioniert nur, wenn Sie sicher wissen, dass Sie NUR diese Array-Schlüssel haben und sonst nichts.

Die Verwendung von array_key_exists() unterstützt nur die gleichzeitige Überprüfung eines Schlüssels, daher müssen Sie beide separat überprüfen:

foreach ($stuff as $value) {
  if (array_key_exists('story', $value) && array_key_exists('message', $value) {
    // story and message
  } else {
    // either one or both keys missing
  }
}

array_key_exists() gibt true zurück, wenn der Schlüssel im Array vorhanden ist, aber es ist eine echte Funktion und viel zu tippen. Das Sprachkonstrukt isset() wird fast dasselbe tun, außer wenn der getestete Wert NULL ist:

foreach ($stuff as $value) {
  if (isset($value['story']) && isset($value['message']) {
    // story and message
  } else {
    // either one or both keys missing
  }
}

Zusätzlich ermöglicht isset die gleichzeitige Überprüfung mehrerer Variablen:

foreach ($stuff as $value) {
  if (isset($value['story'], $value['message']) {
    // story and message
  } else {
    // either one or both keys missing
  }
}

Um den Test für eingestellte Dinge zu optimieren, verwenden Sie besser dieses “if”:

foreach ($stuff as $value) {
  if (isset($value['story']) {
    if (isset($value['message']) {
      // story and message
    } else {
      // only story
    }
  } else {
    // No story - but message not checked
  }
}

1355450cookie-checkSo überprüfen Sie, ob mehrere Array-Schlüssel vorhanden sind

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy