in_array () e matrice multidimensionale


243

Uso in_array()per verificare se esiste un valore in un array come di seguito,

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

//print_r($a);

ma che dire di un array multidimensionale (sotto): come posso verificare quel valore se esiste nel multi-array?

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

print_r($b);

o non dovrei usare in_array()quando si tratta dell'array multidimensionale?


1
La soluzione accettata funziona alla grande ma può portare a risultati non intenzionali quando si effettuano confronti non rigidi a causa della manipolazione del tipo di PHP. Vedi: stackoverflow.com/a/48890256/1579327
Paolo

1
sia la risposta di jwueller che la mia sono risposte corrette alla tua domanda. Ho proposto una soluzione alternativa che estende la funzione di jwueller al fine di evitare un errore comune dovuto alla manipolazione del tipo di PHP quando si effettuano confronti non rigorosi.
Paolo,

1
una fodera:var_dump(array_sum(array_map(function ($tmp) {return in_array('NT',$tmp);}, $multiarray)) > 0);
Agnius Vasiliauskas,

1
@AgniusVasiliauskas soluzione intelligente, ma ha problemi se l'array di primo livello contiene un elemento che non è un array, ad esempio:$multiarray = array( "Hello", array("Mac", "NT"), array("Irix", "Linux"));
Paolo

1
@Paolo Nessuno ti impedisce di espandere la funzione anonima in base alle tue esigenze - in questo caso aggiungi il check in funzione anonima se la variabile $tmpè un array con is_array()funzione. Se non un array, procedere con uno scenario diverso.
Agnius Vasiliauskas,

Risposte:


473

in_array()non funziona su array multidimensionali. Puoi scrivere una funzione ricorsiva per farlo per te:

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

Uso:

$b = array(array("Mac", "NT"), array("Irix", "Linux"));
echo in_array_r("Irix", $b) ? 'found' : 'not found';

1
grazie. la funzione è elegante! lo adoro! Grazie. come posso sapere se ritorna vero o falso mentre il mio schermo mostra qualcosa quando eseguo la tua funzione? Grazie.
laukok,

14
Stavo cercando qualcosa che facesse questo, mi hai appena salvato da scrivere il mio :)
Liam W

1
Funziona benissimo. Quindi, come possiamo cercare e visualizzare la chiave dell'array? Ad esempio: $ b = array (1 => array ("Mac", "NT"), 3 => array ("Irix", "Linux"));
Rashad,

2
@ D.Tate Code su StackOverflow è concesso in licenza in cc by-sa 3.0 con attribuzione obbligatoria (vedi piè di pagina). Puoi semplicemente includere un commento con il permalink a questa risposta.
jwueller,

1
@blamb: è molto intenzionale. Questo è ciò che rende la funzione ricorsiva (da cui , per esempio _r, analoga a print_r()). Discende in tutti gli array nidificati per cercare il valore fino a quando non ci sono più array da trovare. In questo modo, è possibile cercare matrici di complessità arbitraria anziché solo due livelli di profondità.
jwueller,

56

Se conosci la colonna in cui cercare, puoi usare array_search () e array_column ():

$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';
}

Questa idea è nella sezione commenti per array_search () nel manuale di PHP;


15
Puoi anche provare: in_array ('value', array_column ($ arr, 'active'))
ekstro,

1
Hai bisogno di PHP 5.5+ perarray_column
meconroy

1
In questo esempio è possibile ottenere l'UID dell'array secondario corrispondente? @ethmz
zipal_

questo è esattamente quello che voglio
Juned Ansari

Questo è perfetto dopo aver trovato a lungo questa soluzione!
Rohan Ashik,

54

Funzionerà anche questo.

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

Uso:

if(in_array_r($item , $array)){
    // found!
}

3
Intelligente, mi piace questo. Mi chiedo come siano le prestazioni rispetto al foreachloop.
James,

1
Ha funzionato come un fascino.
kemicofa ghost,

1
Non fraintendetemi, mi piace questo approccio per questo caso. Tuttavia restituirà una corrispondenza falsa positiva quando json_encoding $arrayha una chiave associativa che corrisponde $item. Per non parlare del potenziale per abbinare involontariamente parte di una stringa quando c'è una doppia virgoletta nella stringa stessa. Mi fiderei di questa funzione solo in situazioni piccole / semplici come questa domanda.
Mickmackusa,

Nota che questo fallirà se $itemcontiene caratteri che rovinano il primo parametro (espressione regolare) dipreg_match
Paolo

35

Questo lo farà:

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

in_array funziona solo su un array monodimensionale, quindi è necessario eseguire il loop su ciascun array secondario ed eseguire in_array su ciascuno.

Come altri hanno già notato, questo vale solo per un array bidimensionale. Se hai più array nidificati, una versione ricorsiva sarebbe migliore. Vedi le altre risposte per esempi di ciò.


7
Tuttavia, funzionerà solo in una dimensione. Dovrai creare una funzione ricorsiva per verificare ogni profondità.
metrobalderas,

ho eseguito il codice ma ha un errore - Errore di analisi: errore di analisi in C: \ wamp \ www \ 000_TEST \ php \ php.in_array \ index.php sulla riga 21 - che è if (in_array ("Irix", $ value ) grazie.
laukok,

@lauthiamkok: )manca alla fine della riga menzionata.
jwueller,

Grazie, ho risolto la mia risposta. Questo è ciò che accade quando digito troppo velocemente e non rileggo il mio codice.
Alan Geleynse l'

Si dovrebbe sempre chiamare in_array()con il terzo parametro impostato su true. Scopri qui perché: stackoverflow.com/questions/37080581/…
Andreas,

25

se il tuo array è così

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

Usa questo

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

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


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

2
Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo riguardo a come e / o perché risolve il problema migliorerebbe il valore a lungo termine della risposta.
Paperino

3
6 anni dopo, mi ha dato ciò di cui avevo bisogno. array_column()
Sonnellino Coniglio

risposta perfetta per array multidimensionali
Roshan Sankhe

14

Ottima funzione, ma non ha funzionato per me fino a quando non ho aggiunto if($found) { break; }ilelseif

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

11

Per i bambini multidimensionali: in_array('needle', array_column($arr, 'key'))

Per i bambini monodimensionali: in_array('needle', call_user_func_array('array_merge', $arr))


1
! Neat Grazie @ 9ksoft
phaberest il

E a differenza del array_column()metodo, il call_user_func_array('array_merge')metodo funziona anche con array

6

Puoi sempre serializzare il tuo array multidimensionale e fare un strpos:

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

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

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

Vari documenti per le cose che ho usato:


1
È sbagliato. La tua funzione darà anche vero se la stringa di ricerca è contenuta in qualche valore di array (troverà "Irix" in "mytoll Irixus").
mdunisch,

Ho corretto la mia risposta. @ user3351722

in questo modo può essere risolto un problema quando non ce n'è più uno (valore unico), ed è dinamico .. come questo $ in_arr = (bool) strpos (serializzare ($ user_term_was_downloaded), 's: 3: "tid"; s: 2: "' $ a valore> tid. '";');
Anees Hikmat Abu Hmiad il

2
@ I - II non credo che nessuno su Stack Overflow invierebbe codice se non volesse che fosse condiviso. Sentiti libero di usare qualsiasi codice su questo sito per qualsiasi cosa. Di solito aggiungo un commento una riga sopra lo snippet di codice che dice "Grazie Stack Overflow" e quindi incolla l'URL da cui ho trovato il codice.

1
Risposta interessante, sicuramente funziona in determinate situazioni, ma non tutte.
MKN Web Solutions,

4

Da PHP 5.6 esiste una soluzione migliore e più pulita per la risposta originale:

Con una matrice multidimensionale come questa:

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

Possiamo usare l' operatore splat :

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

Se hai chiavi di stringa come questa:

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

Dovrai utilizzare array_valuesper evitare l'errore Cannot unpack array with string keys:

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

2

La soluzione accettata (al momento della scrittura) da 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;
}

È perfettamente corretto ma può avere un comportamento involontario quando si fa un confronto debole (il parametro $strict = false).

A causa della manipolazione del tipo di PHP quando si confrontano entrambi i valori di tipo diverso

"example" == 0

e

0 == "example"

Valuta trueperché "example"viene trasmesso inte trasformato in 0.

(Vedi Perché PHP considera 0 uguale a una stringa? )

Se questo non è il comportamento desiderato , può essere conveniente eseguire il cast di valori numerici su stringa prima di effettuare un confronto non rigoroso:

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

1

Questa è la prima funzione di questo tipo che ho trovato nel manuale di php per in_array . Le funzioni nelle sezioni dei commenti non sono sempre le migliori, ma se non risolve il problema puoi cercare anche lì :)

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

La soluzione di elusive è migliore poiché è solo per array
Gazillion

1

Ecco la mia proposta basata sulla soluzione json_encode () con:

  • opzione maiuscole e minuscole
  • restituendo il conteggio anziché vero
  • ovunque negli array (chiavi e valori)

Se la parola non viene trovata, restituisce comunque 0 uguale a falso .

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

Spero che sia d'aiuto.


Nota che questa funzione corrisponde anche alle sottostringhe : ex 00into 10000o lointo Hello. Inoltre fallirà se l'ago contiene qualsiasi carattere che json_encodefuoriesce , come le doppie virgolette.
Paolo,

Naturalmente dipende da cosa farai, ma per me questa soluzione ha un'esecuzione rapida ed è sufficiente.
Meloman,

1

Credo che al giorno d'oggi puoi semplicemente usare array_key_exists :

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

1

Stavo cercando una funzione che mi permettesse di cercare sia stringhe che array (come ago) nell'array (pagliaio), quindi ho aggiunto alla risposta di @jwueller .

Ecco il mio codice:

/**
 * 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;
}

0

Funziona anche creando prima una nuova matrice unidimensionale da quella originale.

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

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

in_array($needle,$vector);

0

Versione più breve, per array multidimensionali creati in base a set di risultati del database.

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

Restituirà se l'array $ os_list contiene 'XP' nel campo os_version.


0

Ho trovato una soluzione semplice davvero piccola:

Se l'array è:

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

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

)

allora il codice sarà come:

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

0

Ho usato questo metodo funziona per qualsiasi numero di nidificati e non richiede l'hacking

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

-1

Vi preghiamo di provare:

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

Non sono sicuro della necessità, ma potrebbe funzionare per le tue esigenze


2
In che modo la ricerca delle chiavi dell'array farebbe qualcosa? $bLe chiavi dell'array sono solo numeri interi ... non ci sono chiavi specificate in questi array ... e array_keys($b["irix"])genererà un errore, perché $b["irix"]non esiste.
Ben D,


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.