in_array () und mehrdimensionales Array

243

Ich benutze in_array(), um zu überprüfen, ob ein Wert in einem Array wie unten existiert,

$a = array("Mac", "NT", "Irix", "Linux");
if (in_array("Irix", $a)) 
{
    echo "Got Irix";
}

//print_r($a);

Aber was ist mit einem mehrdimensionalen Array (unten) - wie kann ich diesen Wert überprüfen, ob er im Multi-Array vorhanden ist?

$b = array(array("Mac", "NT"), array("Irix", "Linux"));

print_r($b);

oder sollte ich nicht verwenden, in_array()wenn es um das mehrdimensionale Array geht?

Laukok
quelle
1
Die akzeptierte Lösung funktioniert hervorragend, kann jedoch zu unbeabsichtigten Ergebnissen führen, wenn nicht strenge Vergleiche aufgrund des PHP-Typ-Jonglierens durchgeführt werden. Siehe: stackoverflow.com/a/48890256/1579327
Paolo
1
Sowohl die Antwort von jwueller als auch meine sind richtige Antworten auf Ihre Frage. Ich schlug eine alternative Lösung vor, die die Funktion von jwueller erweitert, um einen häufigen Pitfail aufgrund des Jonglierens von PHP-Typen bei nicht strengen Vergleichen zu vermeiden.
Paolo
1
ein Liner:var_dump(array_sum(array_map(function ($tmp) {return in_array('NT',$tmp);}, $multiarray)) > 0);
Agnius Vasiliauskas
1
@AgniusVasiliauskas clevere Lösung, hat aber Probleme, wenn das Array der ersten Ebene ein Element enthält, das kein Array ist, z. B.:$multiarray = array( "Hello", array("Mac", "NT"), array("Irix", "Linux"));
Paolo
1
@Paolo Niemand hindert Sie daran, die anonyme Funktion entsprechend Ihren Anforderungen zu erweitern. Fügen Sie in diesem Fall die Option "Anonyme Funktion einchecken" hinzu, wenn die Variable $tmpein Array mit is_array()Funktion ist. Wenn kein Array - fahren Sie mit einem anderen Szenario fort.
Agnius Vasiliauskas

Antworten:

473

in_array()funktioniert nicht bei mehrdimensionalen Arrays. Sie könnten eine rekursive Funktion schreiben, um dies für Sie zu tun:

function in_array_r($needle, $haystack, $strict = false) {
    foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
            return true;
        }
    }

    return false;
}

Verwendung:

$b = array(array("Mac", "NT"), array("Irix", "Linux"));
echo in_array_r("Irix", $b) ? 'found' : 'not found';
jwueller
quelle
1
Danke. Die Funktion ist elegant! Liebe es! Vielen Dank. Wie kann ich wissen, dass es wahr oder falsch zurückgibt, da auf meinem Bildschirm nichts angezeigt wird, wenn ich Ihre Funktion ausführe? Vielen Dank.
Laukok
14
Ich habe nach etwas gesucht, das dies getan hat. Du hast mich nur
Liam W
1
Es funktioniert großartig. Wie können wir also Array-Schlüssel suchen und anzeigen? Zum Beispiel: $ b = Array (1 => Array ("Mac", "NT"), 3 => Array ("Irix", "Linux"));
Rashad
2
@ D.Tate Code auf StackOverflow ist unter cc by-sa 3.0 lizenziert, wobei eine Zuordnung erforderlich ist (siehe Fußzeile der Seite). Sie können dieser Antwort einfach einen Kommentar mit dem Permalink hinzufügen.
Jwueller
1
@blamb: Das ist sehr beabsichtigt. Dies macht die Funktion rekursiv (daher zum Beispiel _ranalog zu print_r()). Es steigt in alle verschachtelten Arrays ab, um nach dem Wert zu suchen, bis keine Arrays mehr gefunden werden. Auf diese Weise können Sie Arrays beliebiger Komplexität durchsuchen, anstatt nur zwei Ebenen tief.
Jwueller
56

Wenn Sie wissen, nach welcher Spalte gesucht werden soll, können Sie array_search () und array_column () verwenden:

$userdb = Array
(
    (0) => Array
        (
            ('uid') => '100',
            ('name') => 'Sandra Shush',
            ('url') => 'urlof100'
        ),

    (1) => Array
        (
            ('uid') => '5465',
            ('name') => 'Stefanie Mcmohn',
            ('url') => 'urlof5465'
        ),

    (2) => Array
        (
            ('uid') => '40489',
            ('name') => 'Michael',
            ('url') => 'urlof40489'
        )
);

if(array_search('urlof5465', array_column($userdb, 'url')) !== false) {
    echo 'value is in multidim array';
}
else {
    echo 'value is not in multidim array';
}

Diese Idee befindet sich im Kommentarbereich für array_search () im PHP-Handbuch.

Ethmz
quelle
15
Sie können auch versuchen: in_array ('value', array_column ($ arr, 'active'))
ekstro
1
Sie benötigen PHP 5.5+ fürarray_column
meconroy
1
Ist es in diesem Beispiel möglich, die UID des übereinstimmenden Sub-Arrays abzurufen? @ethmz
zipal_
Das ist genau das, was ich will
Juned Ansari
Dies ist perfekt, nachdem Sie diese Lösung lange gefunden haben!
Rohan Ashik
54

Das wird auch funktionieren.

function in_array_r($item , $array){
    return preg_match('/"'.preg_quote($item, '/').'"/i' , json_encode($array));
}

Verwendung:

if(in_array_r($item , $array)){
    // found!
}
NassimPHP
quelle
3
Clever, das gefällt mir. Ich frage mich, wie die Leistung im Vergleich zur foreachSchleife ist.
James
1
Lief wie am Schnürchen.
Kemicofa Ghost
1
Versteh mich nicht falsch, ich mag diesen Ansatz für diesen Fall. Es wird jedoch eine falsch positive Übereinstimmung zurückgegeben, wenn json_encoding eine $arraymit einem passenden assoziativen Schlüssel hat $item. Ganz zu schweigen von der Möglichkeit, einen Teil einer Zeichenfolge unbeabsichtigt abzugleichen, wenn die Zeichenfolge selbst ein doppeltes Anführungszeichen enthält. Ich würde dieser Funktion nur in kleinen / einfachen Situationen wie dieser Frage vertrauen.
Mickmackusa
Beachten Sie, dass dies fehlschlägt, wenn $itemZeichen enthalten sind, die den ersten Parameter (regulärer Ausdruck) vonpreg_match
Paolo
35

Dies wird es tun:

foreach($b as $value)
{
    if(in_array("Irix", $value, true))
    {
        echo "Got Irix";
    }
}

in_arrayarbeitet nur mit einem eindimensionalen Array, daher müssen Sie jedes Sub-Array durchlaufen und in_arrayauf jedem ausführen .

Wie andere angemerkt haben, gilt dies nur für ein zweidimensionales Array. Wenn Sie mehr verschachtelte Arrays haben, ist eine rekursive Version besser. Beispiele hierfür finden Sie in den anderen Antworten.

Alan Geleynse
quelle
7
Dies funktioniert jedoch nur in einer Dimension. Sie müssen eine rekursive Funktion erstellen, um jede Tiefe zu überprüfen.
Metrobalderas
Ich habe den Code ausgeführt, aber er hat einen Fehler - Analysefehler: Analysefehler in C: \ wamp \ www \ 000_TEST \ php \ php.in_array \ index.php in Zeile 21 - das ist if (in_array ("Irix", $ value) ) danke.
Laukok
@lauthiamkok: Am )Ende der genannten Zeile fehlt ein .
Jwueller
Danke, ich habe meine Antwort korrigiert. Das passiert, wenn ich zu schnell tippe und meinen Code nicht erneut lese.
Alan Geleynse
Sie sollten immer in_array()mit dem dritten Parametersatz aufrufen true. Überprüfen Sie hier, warum: stackoverflow.com/questions/37080581/…
Andreas
25

wenn dein Array so ist

$array = array(
              array("name" => "Robert", "Age" => "22", "Place" => "TN"), 
              array("name" => "Henry", "Age" => "21", "Place" => "TVL")
         );

Benutze das

function in_multiarray($elem, $array,$field)
{
    $top = sizeof($array) - 1;
    $bottom = 0;
    while($bottom <= $top)
    {
        if($array[$bottom][$field] == $elem)
            return true;
        else 
            if(is_array($array[$bottom][$field]))
                if(in_multiarray($elem, ($array[$bottom][$field])))
                    return true;

        $bottom++;
    }        
    return false;
}

Beispiel: echo in_multiarray("22", $array,"Age");

rynhe
quelle
21
$userdb = Array
(
    (0) => Array
        (
            ('uid') => '100',
            ('name') => 'Sandra Shush',
            ('url') => 'urlof100'
        ),

    (1) => Array
        (
            ('uid') => '5465',
            ('name') => 'Stefanie Mcmohn',
            ('url') => 'urlof5465'
        ),

    (2) => Array
        (
            ('uid') => '40489',
            ('name') => 'Michael',
            ('url') => 'urlof40489'
        )
);

$url_in_array = in_array('urlof5465', array_column($userdb, 'url'));

if($url_in_array) {
    echo 'value is in multidim array';
}
else {
    echo 'value is not in multidim array';
}
Mukesh Goyal
quelle
2
Während dieser Code die Frage möglicherweise beantwortet, würde die Bereitstellung eines zusätzlichen Kontexts darüber, wie und / oder warum das Problem gelöst wird, den langfristigen Wert der Antwort verbessern.
Donald Duck
3
6 Jahre später gab es mir, was ich brauche. array_column()
NappingRabbit
perfekte Antwort für mehrdimensionale Anordnung
Roshan Sankhe
14

Tolle Funktion, aber es hat bei mir nicht funktioniert, bis ich die if($found) { break; }zum hinzugefügt habeelseif

function in_array_r($needle, $haystack) {
    $found = false;
    foreach ($haystack as $item) {
    if ($item === $needle) { 
            $found = true; 
            break; 
        } elseif (is_array($item)) {
            $found = in_array_r($needle, $item); 
            if($found) { 
                break; 
            } 
        }    
    }
    return $found;
}
Fernando
quelle
11

Für mehrdimensionale Kinder: in_array('needle', array_column($arr, 'key'))

Für eindimensionale Kinder: in_array('needle', call_user_func_array('array_merge', $arr))

Mohd Abdul Mujib
quelle
1
Ordentlich! Danke @ 9ksoft
Phaberest
Und im Gegensatz zur array_column()Methode call_user_func_array('array_merge')funktioniert die Methode auch mit indexbasierten
6

Sie können Ihr mehrdimensionales Array jederzeit serialisieren und Folgendes ausführen strpos:

$arr = array(array("Mac", "NT"), array("Irix", "Linux"));

$in_arr = (bool)strpos(serialize($arr),'s:4:"Irix";');

if($in_arr){
    echo "Got Irix!";
}

Verschiedene Dokumente für Dinge, die ich verwendet habe:


quelle
1
Das ist falsch. Ihre Funktion gibt auch true aus, wenn die Suchzeichenfolge in einem Array-Wert enthalten ist (findet "Irix" in "mytoll Irixus").
Mdunisch
Ich habe meine Antwort korrigiert. @ user3351722
Auf diese Weise kann ein Problem behoben werden, wenn niemand mehr (eindeutiges Tal) vorhanden ist und dynamisch sein soll. 2: "'. $ Value-> tid.'"; ');
Anees Hikmat Abu Hmiad
2
@ I - II glaube nicht, dass jemand auf Stack Overflow Code posten würde, wenn er nicht möchte, dass er geteilt wird. Fühlen Sie sich frei, einen der Codes auf dieser Website für irgendetwas zu verwenden. Normalerweise füge ich eine Zeile über dem Code-Snippet einen Kommentar mit der Aufschrift "Thanks Stack Overflow" hinzu und füge dann die URL ein, unter der ich den Code gefunden habe.
1
Interessante Antwort, funktioniert definitiv in bestimmten Situationen, aber nicht in allen.
MKN Web Solutions
4

Seit PHP 5.6 gibt es eine bessere und sauberere Lösung für die ursprüngliche Antwort:

Mit einem mehrdimensionalen Array wie diesem:

$a = array(array("Mac", "NT"), array("Irix", "Linux"))

Wir können den Splat-Operator verwenden :

return in_array("Irix", array_merge(...$a), true)

Wenn Sie Zeichenfolgenschlüssel wie diesen haben:

$a = array("a" => array("Mac", "NT"), "b" => array("Irix", "Linux"))

Sie müssen verwenden array_values, um den Fehler zu vermeiden Cannot unpack array with string keys:

return in_array("Irix", array_merge(...array_values($a)), true)
Fabien Salles
quelle
2

Die akzeptierte Lösung (zum Zeitpunkt des Schreibens) von jwueller

function in_array_r($needle, $haystack, $strict = false) {
    foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
            return true;
        }
    }

    return false;
}

Ist vollkommen korrekt, kann sich aber bei einem schwachen Vergleich (dem Parameter $strict = false) unbeabsichtigt verhalten .

Aufgrund des PHP-Typ-Jonglierens beim Vergleichen von Werten unterschiedlichen Typs

"example" == 0

und

0 == "example"

Wertet aus, trueweil "example"in umgewandelt intund umgewandelt wird 0.

(Siehe Warum betrachtet PHP 0 als gleich einer Zeichenfolge? )

Wenn dies nicht das gewünschte Verhalten ist , kann es zweckmäßig sein, numerische Werte in Zeichenfolgen umzuwandeln , bevor ein nicht strenger Vergleich durchgeführt wird:

function in_array_r($needle, $haystack, $strict = false) {
    foreach ($haystack as $item) {

        if( ! $strict && is_string( $needle ) && ( is_float( $item ) || is_int( $item ) ) ) {
            $item = (string)$item;
        }

        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
            return true;
        }
    }

    return false;
}
Paolo
quelle
1

Dies ist die erste Funktion dieses Typs, die ich im PHP-Handbuch für in_array gefunden habe . Funktionen in den Kommentaren sind nicht immer die besten, aber wenn sie nicht ausreichen, können Sie auch dort nachsehen :)

<?php
function in_multiarray($elem, $array)
    {
        // if the $array is an array or is an object
         if( is_array( $array ) || is_object( $array ) )
         {
             // if $elem is in $array object
             if( is_object( $array ) )
             {
                 $temp_array = get_object_vars( $array );
                 if( in_array( $elem, $temp_array ) )
                     return TRUE;
             }

             // if $elem is in $array return true
             if( is_array( $array ) && in_array( $elem, $array ) )
                 return TRUE;


             // if $elem isn't in $array, then check foreach element
             foreach( $array as $array_element )
             {
                 // if $array_element is an array or is an object call the in_multiarray function to this element
                 // if in_multiarray returns TRUE, than return is in array, else check next element
                 if( ( is_array( $array_element ) || is_object( $array_element ) ) && $this->in_multiarray( $elem, $array_element ) )
                 {
                     return TRUE;
                     exit;
                 }
             }
         }

         // if isn't in array return FALSE
         return FALSE;
    }
?>
Gazillion
quelle
Die Lösung von elusive ist besser, da sie nur für Arrays
gedacht ist
1

Hier ist mein Vorschlag basierend auf der Lösung json_encode () mit:

  • Option ohne Berücksichtigung der Groß- und Kleinschreibung
  • Rückgabe der Zählung anstelle von true
  • überall in Arrays (Schlüssel und Werte)

Wenn das Wort nicht gefunden wird, wird immer noch 0 gleich false zurückgegeben .

function in_array_count($needle, $haystack, $caseSensitive = true) {
    if(!$caseSensitive) {
        return substr_count(strtoupper(json_encode($haystack)), strtoupper($needle));
    }
    return substr_count(json_encode($haystack), $needle);
}

Ich hoffe es hilft.

Meloman
quelle
Beachten Sie, dass diese Funktion auch Teilzeichenfolgen entspricht : ex 00into 10000oder lointo Hello. Darüber hinaus schlägt fehl, wenn die Nadel alle Zeichen enthält, die json_encodeentkommen , wie doppelte Anführungszeichen.
Paolo
Natürlich hängt es davon ab, was Sie tun werden, aber für mich hat diese Lösung eine schnelle Ausführung und reicht aus.
Meloman
1

Ich glaube, Sie können heutzutage nur array_key_exists verwenden :

<?php
$a=array("Mac"=>"NT","Irix"=>"Linux");
if (array_key_exists("Mac",$a))
  {
  echo "Key exists!";
  }
else
  {
  echo "Key does not exist!";
  }
?>
SrAxi
quelle
1

Ich suchte nach einer Funktion, mit der ich sowohl nach Strings als auch nach Arrays (als Nadel) im Array (Heuhaufen) suchen konnte , also fügte ich der Antwort von @jwueller hinzu .

Hier ist mein Code:

/**
 * Recursive in_array function
 * Searches recursively for needle in an array (haystack).
 * Works with both strings and arrays as needle.
 * Both needle's and haystack's keys are ignored, only values are compared.
 * Note: if needle is an array, all values in needle have to be found for it to
 * return true. If one value is not found, false is returned.
 * @param  mixed   $needle   The array or string to be found
 * @param  array   $haystack The array to be searched in
 * @param  boolean $strict   Use strict value & type validation (===) or just value
 * @return boolean           True if in array, false if not.
 */
function in_array_r($needle, $haystack, $strict = false) {
     // array wrapper
    if (is_array($needle)) {
        foreach ($needle as $value) {
            if (in_array_r($value, $haystack, $strict) == false) {
                // an array value was not found, stop search, return false
                return false;
            }
        }
        // if the code reaches this point, all values in array have been found
        return true;
    }

    // string handling
    foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle)
            || (is_array($item) && in_array_r($needle, $item, $strict))) {
            return true;
        }
    }
    return false;
}
Neuschnee
quelle
0

Es funktioniert auch, zuerst ein neues eindimensionales Array aus dem ursprünglichen zu erstellen.

$arr = array("key1"=>"value1","key2"=>"value2","key3"=>"value3");

foreach ($arr as $row)  $vector[] = $row['key1'];

in_array($needle,$vector);
Banzy
quelle
0

Kürzere Version für mehrdimensionale Arrays, die basierend auf Datenbank-Ergebnismengen erstellt wurden.

function in_array_r($array, $field, $find){
    foreach($array as $item){
        if($item[$field] == $find) return true;
    }
    return false;
}

$is_found = in_array_r($os_list, 'os_version', 'XP');

Wird zurückgegeben, wenn das Array $ os_list 'XP' im Feld os_version enthält.

andreszs
quelle
0

Ich habe eine wirklich kleine einfache Lösung gefunden:

Wenn Ihr Array ist:

Array
(
[details] => Array
    (
        [name] => Dhruv
        [salary] => 5000
    )

[score] => Array
    (
        [ssc] => 70
        [diploma] => 90
        [degree] => 70
    )

)

dann lautet der Code wie folgt:

 if(in_array("5000",$array['details'])){
             echo "yes found.";
         }
     else {
             echo "no not found";
          }
Dhruv Thakkar
quelle
0

Ich habe diese Methode verwendet, funktioniert für eine beliebige Anzahl von verschachtelten und erfordert kein Hacken

<?php
    $blogCategories = [
        'programing' => [
            'golang',
            'php',
            'ruby',
            'functional' => [
                'Erlang',
                'Haskell'
            ]
        ],
        'bd' => [
            'mysql',
            'sqlite'
        ]
    ];
    $it = new RecursiveArrayIterator($blogCategories);
    foreach (new RecursiveIteratorIterator($it) as $t) {
        $found = $t == 'Haskell';
        if ($found) {
           break;
        }
    }
Sr. Libre
quelle
-1

Bitte versuche:

in_array("irix",array_keys($b))
in_array("Linux",array_keys($b["irix"])

Ich bin mir nicht sicher über die Notwendigkeit, aber dies könnte für Ihre Anforderung funktionieren

sparco
quelle
2
Wie würde das Durchsuchen der Array-Schlüssel etwas bewirken? $bDie Array-Schlüssel sind nur Ganzzahlen ... in diesen Arrays sind keine Schlüssel angegeben ... und es array_keys($b["irix"])wird nur ein Fehler ausgegeben, da dieser $b["irix"]nicht vorhanden ist.
Ben D