in_array () และอาร์เรย์หลายมิติ


243

ฉันใช้in_array()เพื่อตรวจสอบว่ามีค่าอยู่ในอาร์เรย์เหมือนด้านล่างหรือไม่

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

//print_r($a);

แต่สิ่งที่เกี่ยวกับอาร์เรย์หลายมิติ (ด้านล่าง) - ฉันจะตรวจสอบค่านั้นว่ามีอยู่ในหลายอาร์เรย์ได้อย่างไร

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

print_r($b);

หรือฉันไม่ควรใช้in_array()เมื่อมาถึงอาร์เรย์หลายมิติ?


1
โซลูชันที่ได้รับการยอมรับนั้นใช้งานได้ดี แต่อาจนำไปสู่ผลลัพธ์ที่ไม่ได้ตั้งใจเมื่อทำการเปรียบเทียบที่ไม่เข้มงวดเนื่องจากการเล่นกลประเภทของ PHP ดู: stackoverflow.com/a/48890256/1579327
เปาโล

1
ทั้งคำตอบของjwuellerและของฉันเป็นคำตอบที่ถูกต้องสำหรับคำถามของคุณ ฉันเสนอโซลูชันทางเลือกที่ขยายฟังก์ชั่นของjwuellerเพื่อหลีกเลี่ยง pitfail ทั่วไปเนื่องจากการเล่นกลประเภท PHP เมื่อทำการเปรียบเทียบที่ไม่เข้มงวด
เปาโล

1
สายการบินหนึ่ง:var_dump(array_sum(array_map(function ($tmp) {return in_array('NT',$tmp);}, $multiarray)) > 0);
Agnius Vasiliauskas

1
@AgniusVasiliauskas วิธีแก้ปัญหาที่ฉลาด แต่มีปัญหาหากอาร์เรย์ระดับแรกมีรายการที่ไม่ใช่อาร์เรย์ตัวอย่างเช่น:$multiarray = array( "Hello", array("Mac", "NT"), array("Irix", "Linux"));
Paolo

1
@ เปาโลไม่มีใครหยุดคุณจากการขยายฟังก์ชั่นที่ไม่ระบุตัวตนตามความต้องการของคุณ - ในกรณีนี้เพิ่มการตรวจสอบในฟังก์ชั่นที่ไม่ระบุชื่อถ้าตัวแปร$tmpเป็นอาร์เรย์ที่มีis_array()ฟังก์ชั่น ถ้าไม่ใช่อาเรย์ให้ดำเนินการตามสถานการณ์สมมติอื่น
Agnius Vasiliauskas

คำตอบ:


473

in_array()ไม่ทำงานในอาร์เรย์หลายมิติ คุณสามารถเขียนฟังก์ชันแบบเรียกซ้ำเพื่อทำสิ่งนั้นเพื่อคุณ:

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

การใช้งาน:

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

1
ขอบคุณ. ฟังก์ชั่นสง่างาม! รักมัน! ขอบคุณ ฉันจะรู้ได้อย่างไรว่ามันคืนจริงหรือเท็จเมื่อหน้าจอของฉันแสดงอะไรเมื่อฉันเรียกใช้ฟังก์ชันของคุณ? ขอบคุณ
laukok

14
ผมกำลังมองหาบางสิ่งบางอย่างที่ไม่ได้นี้คุณเพียงแค่บันทึกฉันจากการเขียน :) ของตัวเอง
เลียม W

1
มันใช้งานได้ดี แล้วเราจะค้นหาและแสดงคีย์อาเรย์ได้อย่างไร ตัวอย่างเช่น: $ b = array (1 => array ("Mac", "NT"), 3 => array ("Irix", "Linux"));
Rashad

2
@ D.Tate Code ใน StackOverflow ได้รับอนุญาตภายใต้cc by-sa 3.0พร้อมการระบุแหล่งที่มา (ดูส่วนท้ายของหน้า) คุณสามารถรวมความคิดเห็นพร้อมลิงก์ไปยังคำตอบนี้
jwueller

1
@blamb: นั่นเป็นความตั้งใจมาก นี่คือสิ่งที่ทำให้ฟังก์ชั่นซ้ำ ( _rเช่นที่คล้ายกับprint_r()ตัวอย่าง) มันจะเรียงเข้าไปในอาร์เรย์ที่ซ้อนกันทั้งหมดเพื่อค้นหาค่าจนกว่าจะไม่พบอาร์เรย์อีกต่อไป ด้วยวิธีนี้คุณสามารถค้นหาผ่านอาร์เรย์ที่มีความซับซ้อนตามอำเภอใจแทนที่จะเป็นเพียงสองระดับ
jwueller

56

หากคุณทราบว่าต้องการค้นหาคอลัมน์ใดคุณสามารถใช้ array_search () และ 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';
}

แนวคิดนี้อยู่ในส่วนข้อคิดเห็นสำหรับ array_search () ในคู่มือ PHP;


15
คุณสามารถลอง: in_array ('value', array_column ($ arr, 'active'))
ekstro

1
คุณต้องมี PHP 5.5+ สำหรับarray_column
meconroy

1
เป็นไปได้หรือไม่ที่จะรับ uid ของอาร์เรย์ย่อยที่ตรงกันในตัวอย่างนี้ @ethmz
zipal_

ตรงนี้เป็นสิ่งที่ฉันต้องการ
Juned Ansari

มันสมบูรณ์แบบหลังจากพบโซลูชันนี้มานานแล้ว!
Rohan Ashik

54

มันจะใช้ได้เช่นกัน

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

การใช้งาน:

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

3
ฉลาดฉันชอบสิ่งนี้ ฉันสงสัยว่าประสิทธิภาพการทำงานเป็นอย่างไรเมื่อเปรียบเทียบกับforeachลูป
James

1
ทำงานเหมือนจับใจ
kemicofa ghost

1
อย่าเข้าใจฉันผิดฉันชอบวิธีการนี้ในกรณีนี้ แต่มันจะกลับมาจับคู่บวกปลอมเมื่อ json_encoding ที่มีการเชื่อมโยงที่สำคัญที่ตรงกับ$array $itemไม่ต้องพูดถึงความเป็นไปได้ในการจับคู่ส่วนของสตริงโดยไม่ได้ตั้งใจเมื่อมีเครื่องหมายคำพูดคู่ในสตริงนั้น ฉันจะไว้วางใจฟังก์ชั่นนี้ในสถานการณ์เล็ก ๆ / ง่ายๆเช่นคำถามนี้
mickmackusa

โปรดทราบว่าสิ่งนี้จะล้มเหลวหาก$itemมีอักขระที่ขันสกรูพารามิเตอร์แรก (นิพจน์ปกติ) ของpreg_match
Paolo

35

สิ่งนี้จะทำ:

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

in_arrayทำงานในอาเรย์หนึ่งมิติเท่านั้นดังนั้นคุณต้องวนลูปย่อยแต่ละอาเรย์แล้วรันin_arrayในอาเรย์แต่ละอัน

ดังที่คนอื่น ๆ ได้กล่าวไว้สิ่งนี้จะใช้สำหรับอาเรย์ 2 มิติเท่านั้น หากคุณมีอาร์เรย์ที่ซ้อนกันมากกว่ารุ่นที่เรียกซ้ำจะดีกว่า ดูคำตอบอื่น ๆ สำหรับตัวอย่างของสิ่งนั้น


7
อย่างไรก็ตามสิ่งนี้จะใช้ได้ในมิติเดียวเท่านั้น คุณจะต้องสร้างฟังก์ชั่นวนซ้ำเพื่อตรวจสอบความลึกแต่ละครั้ง
metrobalderas

ฉันรันรหัส แต่มีข้อผิดพลาด - ข้อผิดพลาดในการแยกวิเคราะห์: ข้อผิดพลาดในการแยกใน C: \ wamp \ www \ 000_TEST \ php \ php.in_array \ index.php ในบรรทัดที่ 21 - ซึ่งเป็นถ้า (in_array ("Irix", $ value ) ขอบคุณ
laukok

@lauthiamkok: มีการ)หายไปในตอนท้ายของบรรทัดที่กล่าวถึง
jwueller

ขอบคุณฉันคงคำตอบของฉัน นั่นคือสิ่งที่จะเกิดขึ้นเมื่อฉันพิมพ์เร็วเกินไปและอย่าอ่านซ้ำรหัสของฉัน
Alan Geleynse

คุณควรโทรกับชุดพารามิเตอร์ที่สามไปin_array() trueลองดูที่นี่ทำไม: stackoverflow.com/questions/37080581/…
Andreas

25

ถ้าอาร์เรย์ของคุณเป็นเช่นนี้

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

ใช้สิ่งนี้

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

ตัวอย่าง: 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
ในขณะที่รหัสนี้อาจตอบคำถามให้บริบทเพิ่มเติมเกี่ยวกับวิธีการและ / หรือทำไมมันแก้ปัญหาจะปรับปรุงค่าระยะยาวของคำตอบ
Donald Duck

3
6 ปีต่อมามันให้สิ่งที่ฉันต้องการ array_column()
NappingRabbit

คำตอบที่สมบูรณ์แบบสำหรับอาร์เรย์หลายมิติ
Roshan Sankhe

14

ฟังก์ชั่นที่ยอดเยี่ยม แต่มันใช้งานไม่ได้สำหรับฉันจนกว่าฉันจะเพิ่มลงif($found) { break; }ในelseif

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

สำหรับเด็กหลายมิติ: in_array('needle', array_column($arr, 'key'))

สำหรับเด็กหนึ่งมิติ: in_array('needle', call_user_func_array('array_merge', $arr))


1
เรียบร้อย! ขอบคุณ @ 9ksoft
phaberest

ซึ่งแตกต่างจากarray_column()วิธีการcall_user_func_array('array_merge')วิธีนี้ยังทำงานร่วมกับอาร์เรย์เด็กที่ใช้ดัชนี, +1

6

คุณก็สามารถเป็นอันดับอาร์เรย์หลายมิติของคุณและทำstrpos:

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

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

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

เอกสารต่างๆสำหรับสิ่งที่ฉันใช้:


1
นั่นเป็นสิ่งที่ผิด ฟังก์ชั่นของคุณจะเป็นจริงหากสตริงการค้นหามีอยู่ในบางค่าอาร์เรย์ (จะพบ "Irix" ใน "mytoll Irixus")
mdunisch

ฉันแก้ไขคำตอบของฉันแล้ว @ user3351722

วิธีนี้สามารถแก้ไขปัญหาเมื่อไม่มีใคร (หุบเขาที่ไม่ซ้ำกัน) และเป็นแบบไดนามิก .. เช่นนี้ $ in_arr = (บูล) strpos (เป็นอนุกรม ($ user_term_was_downloaded), 's: 3: "tid"; s: 2: "' $ มูลค่า> Tid.. '";');
Anees Hikmat Abu Hmiad

2
@ I - II ไม่คิดว่าทุกคนใน Stack Overflow จะโพสต์รหัสหากพวกเขาไม่ต้องการให้แชร์ อย่าลังเลที่จะใช้รหัสใด ๆ ในเว็บไซต์นี้เพื่ออะไร ฉันมักจะเพิ่มความคิดเห็นหนึ่งบรรทัดด้านบนของโค้ดที่ระบุว่า "Thanks Stack Overflow" แล้ววาง URL ที่ฉันพบโค้ดจาก

1
คำตอบที่น่าสนใจทำงานได้แน่นอนในบางสถานการณ์ แต่ไม่ใช่ทั้งหมด
MKN Web Solutions

4

เนื่องจากPHP 5.6มีทางออกที่ดีกว่าและสะอาดกว่าสำหรับคำตอบเดิม:

ด้วยอาร์เรย์หลายมิติเช่นนี้

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

เราสามารถใช้เครื่องหมายผู้ประกอบการ :

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

หากคุณมีคีย์สตริงเช่นนี้:

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

คุณจะต้องใช้array_valuesเพื่อหลีกเลี่ยงข้อผิดพลาดCannot unpack array with string keys:

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

2

โซลูชั่นที่ได้รับการยอมรับ (ในเวลาที่เขียน) โดย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;
}

ถูกต้องสมบูรณ์ แต่อาจมีพฤติกรรมที่ไม่ตั้งใจเมื่อทำการเปรียบเทียบที่ไม่รัดกุม (พารามิเตอร์$strict = false)

เนื่องจากการเล่นกลประเภท PHP เมื่อเปรียบเทียบค่าของประเภทที่แตกต่างกันทั้งสอง

"example" == 0

และ

0 == "example"

ประเมินtrueเพราะ"example"จะหล่อไปและกลายเป็นint0

(ดูทำไม PHP พิจารณา 0 ให้เท่ากับสตริง )

หากนี่ไม่ใช่พฤติกรรมที่ต้องการสามารถสะดวกในการแปลงค่าตัวเลขไปยังสตริงก่อนทำการเปรียบเทียบที่ไม่เข้มงวด:

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

นี้เป็นฟังก์ชั่นแรกของประเภทนี้ที่ผมพบว่าในคู่มือ php สำหรับ in_array ฟังก์ชั่นในส่วนความคิดเห็นนั้นไม่ได้ดีที่สุดเสมอไป แต่ถ้ามันไม่ได้ทำเคล็ดลับ

<?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 นั้นดีกว่าเพราะมันมีไว้สำหรับอาร์เรย์
Gazillion

1

นี่คือข้อเสนอของฉันตาม json_encode () โซลูชันด้วย:

  • ตัวเลือกกรณีตาย
  • คืนค่าจำนวนแทนที่จะเป็นจริง
  • ที่ใดก็ได้ในอาร์เรย์ (คีย์และค่า)

ถ้าเป็นคำไม่พบก็ยังคงส่งกลับ0เท่ากับเท็จ

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

หวังว่ามันจะช่วย


โปรดทราบว่าฟังก์ชั่นนี้ตรงกับสตริงเกินไป: อดีต00เข้า10000หรือออกเป็นlo Helloนอกจากนี้จะล้มเหลวคือเข็มประกอบด้วยอักขระใด ๆ ที่json_encodeหนีเช่นเครื่องหมายคำพูดคู่
เปาโล

แน่นอนมันขึ้นอยู่กับสิ่งที่คุณจะทำ แต่สำหรับฉันแล้วโซลูชันนี้มีการดำเนินการที่รวดเร็วและเพียงพอ
Meloman

1

ฉันเชื่อว่าคุณสามารถใช้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

ฉันกำลังมองหาฟังก์ชั่นที่จะให้ฉันค้นหาทั้งสตริงและอาร์เรย์ (เหมือนเข็ม) ในอาร์เรย์ ( เฮย์สแต็ค ) ดังนั้นฉันจึงเพิ่มคำตอบโดย @jwueller@jwueller

นี่คือรหัสของฉัน:

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

มันทำงานได้ด้วยการสร้าง Array unidimensional ขึ้นมาใหม่จากเดิม

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

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

in_array($needle,$vector);

0

เวอร์ชันที่สั้นกว่าสำหรับอาร์เรย์หลายมิติที่สร้างขึ้นตามชุดผลลัพธ์ฐานข้อมูล

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 มี 'XP' ในฟิลด์ os_version


0

ฉันพบวิธีแก้ปัญหาง่ายๆขนาดเล็กมาก:

ถ้าอาร์เรย์ของคุณคือ:

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

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

)

จากนั้นรหัสจะเป็นดังนี้:

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

0

ฉันใช้วิธีนี้ใช้งานได้กับจำนวนที่ซ้อนกันและไม่จำเป็นต้องแฮ็ก

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

กรุณาลอง:

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

ฉันไม่แน่ใจเกี่ยวกับความต้องการ แต่สิ่งนี้อาจทำงานได้ตามความต้องการของคุณ


2
การค้นหาคีย์อาร์เรย์ทำได้อย่างไร $bคีย์อาเรย์เป็นเพียงจำนวนเต็ม ... ไม่มีคีย์ที่ระบุในอาเรย์เหล่านี้ ... และarray_keys($b["irix"])จะเกิดข้อผิดพลาดเนื่องจาก$b["irix"]ไม่มีอยู่
เบ็น D

-1

แล้ว array_search ล่ะ? ดูเหมือนว่าจะเร็วกว่า foreach ตามhttps://gist.github.com/Ocramius/1290076 ..

if( array_search("Irix", $a) === true) 
{
    echo "Got Irix";
}

จริงๆแล้ว array_search ไม่สามารถเรียกซ้ำได้ดังนั้นจึงไม่สามารถใช้งานได้ ฉันหวังว่ามันจะเพราะมันสะอาดและเรียบง่าย php.net/manual/en/function.array-search.php
MatthewLee

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.