in_array () ve çok boyutlu dizi


243

in_array()Aşağıdaki gibi bir dizide bir değer olup olmadığını kontrol etmek için kullanın ,

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

//print_r($a);

Peki ya çok boyutlu bir dizi hakkında (aşağıda) - bu değeri çoklu dizide olup olmadığını nasıl kontrol edebilirim?

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

print_r($b);

ya in_array()da çok boyutlu diziye geldiğinde kullanmamalıyım ?


1
Kabul edilen çözüm harika çalışıyor ancak PHP'nin tür hokkabazlığı nedeniyle katı olmayan karşılaştırmalar yaparken istenmeyen sonuçlara yol açabilir . Bakınız: stackoverflow.com/a/48890256/1579327
Paolo

1
Her iki jwueller 'ın cevabı ve mayın sorunuzun doğru cevaplar. Ben uzanan alternatif bir çözüm önerdi jwueller olmayan sıkı karşılaştırmalar yaparken nedeniyle PHP'nin tip hokkabazlık ortak pitfail önlemek amacıyla 'nin fonksiyonu.
Paolo

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

1
@AgniusVasiliauskas akıllı çözüm, ancak birinci düzey dizi dizi olmayan bir öğe içeriyorsa sorunları var, örn:$multiarray = array( "Hello", array("Mac", "NT"), array("Irix", "Linux"));
Paolo

1
@Paolo Kimse anonim işlevi ihtiyaçlarınıza göre genişletmenizi engellemez - bu durumda değişken işlevli $tmpbir dizi ise anonim işlevde check-in ekleyin is_array(). Dizi değilse - farklı senaryo ile devam edin.
Agnius Vasiliauskas

Yanıtlar:


473

in_array()çok boyutlu dizilerde çalışmaz. Bunu sizin için tekrarlayan bir işlev yazabilirsiniz:

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

Kullanımı:

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

1
teşekkür ederim. işlevi zarif! Sevdim! Teşekkürler. fonksiyonumu çalıştırdığımda ekranımın herhangi bir şey gösterdiği için doğru veya yanlış döndüğünü nasıl bilebilirim? Teşekkürler.
laukok

14
Bunu yapan bir şey arıyordum, sadece kendimi yazmaktan kurtardın :)
Liam W

1
Harika çalışıyor. Öyleyse dizi anahtarını nasıl arayabilir ve görüntüleyebiliriz? Örneğin: $ b = dizi (1 => dizi ("Mac", "NT"), 3 => dizi ("Irix", "Linux"));
Rashad

2
@ D. StackOverflow üzerindeki Tarih Kodu, atıf gerekli olan cc by-sa 3.0 altında lisanslanmıştır (bkz. Sayfa altbilgisi). Bu yanıta kalıcı bağlantı içeren bir yorum ekleyebilirsiniz.
jwueller

1
@blamb: Bu çok kasıtlı. Fonksiyonu özyinelemeli yapan budur (dolayısıyla, örneğin _r, benzer print_r()). Bulunacak başka diziler kalmayana kadar değeri aramak için tüm iç içe dizilere iner. Bu şekilde, sadece iki seviye derinlik yerine, rastgele karmaşıklık dizileri arasında arama yapabilirsiniz.
jwueller

56

Hangi sütunda arama yapacağınızı biliyorsanız, array_search () ve array_column () kullanabilirsiniz:

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

Bu fikir, PHP kılavuzundaki array_search () için yorumlar bölümünde bulunmaktadır;


15
Bunu da deneyebilirsiniz: in_array ('değer', dizi_column ($ arr, 'aktif'))
ekstro

1
PHP 5.5+ için ihtiyacınız vararray_column
meconroy

1
Bu örnekte eşleşen alt dizinin uid'ini almak mümkün müdür? @ethmz
zipal_

Bu tam olarak istediğim şey
Juned Ansari

Uzun zamandır bu çözümü bulduktan sonra bu mükemmel!
Rohan Ashik

54

Bu da işe yarayacaktır.

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

Kullanımı:

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

3
Zeki, bunu beğendim. foreachDöngü ile karşılaştırıldığında performansın nasıl olduğunu merak ediyorum .
James

1
Bir cazibe gibi çalıştı.
kemicofa hayalet

1
Beni yanlış anlamayın, bu dava için bu yaklaşımı seviyorum. Ancak json_encoding ile eşleşen $arraybir ilişkilendirme anahtarı olduğunda yanlış pozitif bir eşleşme döndürür $item. Dizenin kendisinde çift tırnak olduğunda, dizenin bir kısmını istemeden eşleştirme potansiyelinden bahsetmiyoruz. Bu işleve yalnızca bu soru gibi küçük / basit durumlarda güvenirim.
mickmackusa

$itempreg_match
Paolo

35

Bunu yapacak:

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

in_arrayyalnızca tek boyutlu bir dizi üzerinde çalışır, bu nedenle her alt dizi üzerinde döngü yapmanız ve in_arrayher birinde çalışmanız gerekir .

Diğerlerinin de belirttiği gibi, bu sadece 2 boyutlu bir dizi için olacaktır. Daha fazla iç içe diziniz varsa, yinelenen bir sürüm daha iyi olur. Bunun örnekleri için diğer cevaplara bakınız.


7
Ancak, bu yalnızca bir boyutta işe yarayacaktır. Her derinliği kontrol etmek için özyinelemeli bir işlev oluşturmanız gerekir.
metrobalderas

kodu çalıştırdım ama bir hata var - Ayrıştırma hatası: C: ​​\ wamp \ www \ 000_TEST \ php \ php.in_array \ index.php satır 21 - eğer (in_array ("Irix", $ değer) ) teşekkürler.
laukok

@lauthiamkok: )Belirtilen satırın sonunda bir eksik var .
jwueller

Teşekkürler, cevabımı düzelttim. Çok hızlı yazdığımda ve kodumu tekrar okumadığımda bu olur.
Alan Geleynse

Her zaman in_array()üçüncü parametre olarak ayarlanmış olarak çağırmalısınız true. Nedenini buradan kontrol edin: stackoverflow.com/questions/37080581/…
Andreas

25

diziniz böyle ise

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

Bunu kullan

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

misal : 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
Bu kod soruyu cevaplayabilirken, sorunun nasıl ve / veya neden çözüldüğüne ilişkin ek bağlam sağlamak yanıtlayıcının uzun vadeli değerini artıracaktır.
Donald Duck

3
6 yıl sonra bana ihtiyacım olanı verdi. array_column()
NappingRabbit

çok boyutlu dizi için mükemmel cevap
Roshan Sankhe

14

İ ekledi kadar büyük işlev, ama benim için işe yaramadı if($found) { break; }içinelseif

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

Çok Boyutlu Çocuklar İçin: in_array('needle', array_column($arr, 'key'))

Bir Boyutlu Çocuklar İçin: in_array('needle', call_user_func_array('array_merge', $arr))


1
Temiz! Thanks @ 9ksoft
phaberest

Ve array_column()yöntemin aksine , bu call_user_func_array('array_merge')yöntem indeks tabanlı alt dizilerle de çalışır, +1

6

Her zaman çok boyutlu dizinizi serileştirebilir ve strposşunları yapabilirsiniz :

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

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

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

Kullandığım şeyler için çeşitli dokümanlar:


1
Bu yanlış. Arama dizesi bir dizi değeri içeriyorsa da işleviniz true değerini verir ("mytoll Irixus" içinde "Irix" i bulur).
mdunisch

Cevabımı düzelttim. @ user3351722

daha fazla (benzersiz vale) olmadığında ve dinamik olduğu için bu şekilde bir sorun düzeltilebilir. 2: "' $ değer-> tid.. '";');
Anees Hikmat Abu Hmiad

2
@ I - II, Stack Overflow'daki kimsenin paylaşılmasını istemiyorlarsa kod göndereceğini düşünmüyor. Bu web sitesindeki herhangi bir kodu herhangi bir şey için kullanmaktan çekinmeyin. Genellikle kod parçacığının üzerine "Teşekkür Yığını Taşması" yazan bir satır ekleyin ve sonra kodu bulduğum URL'yi yapıştırıyorum.

1
İlginç bir cevap, kesinlikle belirli durumlarda çalışır, ancak hepsi değil.
MKN Web Solutions

4

Yana PHP 5.6 bir orada daha iyi ve daha temiz orijinal cevap için çözüm:

Bunun gibi çok boyutlu bir dizi ile:

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

Uyarıcı operatörünü kullanabiliriz :

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

Bunun gibi dize anahtarlarınız varsa:

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

array_valuesHatayı önlemek için kullanmanız gerekecek Cannot unpack array with string keys:

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

2

Kabul edilen çözelti tarafından (yazma anda) 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;
}

Mükemmel doğrudur, ancak zayıf karşılaştırma yaparken (parametre $strict = false) istenmeyen davranışlar gösterebilir .

Farklı türdeki değerleri karşılaştırırken PHP'nin tür hokkabazlığı nedeniyle

"example" == 0

ve

0 == "example"

Değerlendirilir, trueçünkü "example"döküm yapılır intve dönüştürülür 0.

(Bkz. PHP neden 0'ın bir dizeye eşit olduğunu düşünüyor? )

Bu istenen davranış değilse, katı olmayan bir karşılaştırma yapmadan önce sayısal değerleri dizeye dökmek uygun olabilir:

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

Bu, in_array için php kılavuzunda bulduğum bu tür ilk işlevdir . Yorum bölümlerindeki işlevler her zaman en iyisi değildir, ancak hile yapmazsa oraya da bakabilirsiniz :)

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

elusive'ın çözümü sadece diziler için daha iyi
Gazillion

1

İşte benim teklif json_encode () çözümüne dayalı :

  • büyük / küçük harfe duyarlı olmayan seçenek
  • sayımı true yerine döndürme
  • dizilerin herhangi bir yerinde (anahtarlar ve değerler)

Sözcük bulunamazsa, yine de 0'a false değerine döner .

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

Umarım yardımcı olur.


Bu işlevin alt dizelerle de eşleştiğini unutmayın : ex 00into 10000veya lointo Hello. Ayrıca , iğnejson_encode çift ​​tırnaklar gibi kaçan herhangi bir karakter içeriyorsa başarısız olur .
Paolo

Tabii ki ne yapacağınıza bağlı, ama benim için bu çözüm hızlı bir şekilde yürütüldü ve yeterlidir.
Meloman

1

Ben sadece bugünlerde array_key_exists kullanabilirsiniz inanıyorum :

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

1

Bana dizi (haystack) dizeleri ve dizileri (iğne gibi) arama izin verecek bir işlev arıyordum , bu yüzden @jwueller tarafından cevap ekledi .

İşte benim kod:

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

İlk önce orijinalinden yeni bir tek boyutlu Dizi oluşturmak için de çalışır.

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

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

in_array($needle,$vector);

0

Veritabanı sonuç kümelerine dayalı olarak oluşturulan çok boyutlu diziler için daha kısa sürüm.

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

$ Os_list dizisi os_version alanında 'XP' içeriyorsa dönecektir.


0

Gerçekten küçük ve basit bir çözüm buldum:

Diziniz:

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

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

)

kod şöyle olacaktır:

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

0

Bu yöntem, herhangi bir sayıda iç içe geçmiş ve hack gerektirmeyen çalışır

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

Deneyin lütfen:

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

İhtiyaçtan emin değilim, ancak bu gereksiniminiz için işe yarayabilir


2
Dizi anahtarlarında nasıl arama yapılır? $b'nin dizi anahtarları sadece tamsayıdır ... bu dizilerde belirtilen anahtar yoktur ... ve array_keys($b["irix"])sadece bir hata verir, çünkü $b["irix"]yoktur.
Ben D


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.