in_array () và mảng đa chiều


243

Tôi sử dụng in_array()để kiểm tra xem một giá trị có tồn tại trong một mảng như dưới đây không,

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

//print_r($a);

nhưng còn một mảng nhiều chiều (bên dưới) - làm thế nào tôi có thể kiểm tra giá trị đó xem nó có tồn tại trong đa mảng không?

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

print_r($b);

hoặc tôi không nên sử dụng in_array()khi đến với mảng đa chiều?


1
Giải pháp được chấp nhận hoạt động rất tốt nhưng có thể dẫn đến kết quả ngoài ý muốn khi thực hiện so sánh không nghiêm ngặt do cách tung hứng của PHP. Xem: stackoverflow.com/a/48890256/1579327
Paolo

1
cả câu trả lời của jwueller và của tôi đều là câu trả lời chính xác cho câu hỏi của bạn. Tôi đã đề xuất một giải pháp thay thế giúp mở rộng chức năng của jwueller để tránh một pitfail thông thường do kiểu tung hứng của PHP khi thực hiện các so sánh không nghiêm ngặt.
Paolo

1
một lớp lót:var_dump(array_sum(array_map(function ($tmp) {return in_array('NT',$tmp);}, $multiarray)) > 0);
Ag Pa Vasiliauskas

1
@AgniusVasiliauskas giải pháp thông minh, nhưng có vấn đề nếu mảng cấp đầu tiên chứa một mục không phải là một mảng, ví dụ:$multiarray = array( "Hello", array("Mac", "NT"), array("Irix", "Linux"));
Paolo

1
@Paolo Không ai ngăn bạn mở rộng chức năng ẩn danh theo nhu cầu của bạn - trong trường hợp này hãy thêm kiểm tra chức năng ẩn danh nếu biến $tmplà một mảng có is_array()chức năng. Nếu không phải là một mảng - tiến hành với kịch bản khác nhau.
Ag Pa Vasiliauskas

Câu trả lời:


473

in_array()không hoạt động trên các mảng đa chiều. Bạn có thể viết một hàm đệ quy để làm điều đó cho bạn:

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

Sử dụng:

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

1
cảm ơn bạn. Chức năng là thanh lịch! yêu nó! cảm ơn. Làm thế nào tôi có thể biết nó trả về đúng hay sai khi màn hình của tôi hiển thị bất cứ điều gì khi tôi chạy chức năng của bạn? cảm ơn.
laukok

14
Tôi đang tìm kiếm thứ gì đó đã làm điều này, bạn vừa cứu tôi khỏi việc tự viết :)
Liam W

1
Nó hoạt động rất tốt. Vậy làm thế nào chúng ta có thể tìm kiếm và hiển thị khóa mảng? Ví dụ: $ b = mảng (1 => mảng ("Mac", "NT"), 3 => mảng ("Irix", "Linux"));
Rashad

2
@ D.Tate Code trên StackOverflow được cấp phép theo cc by-sa 3.0 với yêu cầu ghi công (xem phần chân trang). Bạn chỉ có thể bao gồm một bình luận với permalink cho câu trả lời này.
jwueller

1
@blamb: Điều đó rất có chủ ý. Đây là những gì làm cho hàm đệ quy (do đó _r, tương tự print_r(), ví dụ). Nó đi xuống tất cả các mảng lồng nhau để tìm kiếm giá trị cho đến khi không còn mảng nào được tìm thấy. Bằng cách này, bạn có thể tìm kiếm thông qua các mảng phức tạp tùy ý thay vì chỉ sâu hai cấp.
jwueller

56

Nếu bạn biết cột nào cần tìm kiếm, bạn có thể sử dụng Array_search () và 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';
}

Ý tưởng này nằm trong phần bình luận cho mảng_search () trên hướng dẫn PHP;


15
Bạn cũng có thể thử: in_array ('value', Array_column ($ Array, 'active'))
ekstro

1
Bạn cần PHP 5.5+ choarray_column
meconroy

1
Có thể lấy uid của mảng con phù hợp trong ví dụ này không? @ethmz
zipal_

đây chính xác là những gì tôi muốn
Juned Ansari

Điều này là hoàn hảo sau một thời gian dài tìm thấy giải pháp này!
Rohan Ashik

54

Điều này cũng sẽ làm việc.

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

Sử dụng:

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

3
Thông minh, tôi thích điều này. Tôi tự hỏi hiệu suất là như thế nào so với foreachvòng lặp.
James

1
Làm việc như người ở.
kemicofa ghost

1
Đừng hiểu lầm tôi, tôi thích cách tiếp cận này trong trường hợp này. Tuy nhiên, nó sẽ trả về kết quả dương tính giả khi json_encoding một $arraykhóa có khóa kết hợp khớp $item. Chưa kể đến khả năng vô tình khớp một phần của chuỗi khi có một trích dẫn kép trong chính chuỗi đó. Tôi sẽ chỉ tin tưởng chức năng này trong các tình huống nhỏ / đơn giản như câu hỏi này.
mickmackusa

Lưu ý rằng điều này sẽ thất bại nếu $itemchứa các ký tự làm hỏng tham số đầu tiên (biểu thức chính quy) củapreg_match
Paolo

35

Điều này sẽ làm điều đó:

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

in_arraychỉ hoạt động trên một mảng một chiều, vì vậy bạn cần lặp qua từng mảng phụ và chạy in_arraytrên từng mảng .

Như những người khác đã lưu ý, điều này sẽ chỉ dành cho một mảng 2 chiều. Nếu bạn có nhiều mảng lồng nhau hơn, một phiên bản đệ quy sẽ tốt hơn. Xem các câu trả lời khác cho ví dụ về điều đó.


7
Tuy nhiên, điều này sẽ chỉ hoạt động trong một chiều. Bạn sẽ phải tạo một hàm đệ quy để kiểm tra từng độ sâu.
metrobalderas

Tôi đã chạy mã nhưng nó có lỗi - Lỗi phân tích cú pháp: lỗi phân tích cú pháp trong C: \ wamp \ www \ 000_TEST \ php \ php.in_array \ index.php trên dòng 21 - đó là if (in_array ("Irix", $ value ) cảm ơn.
laukok

@lauthiamkok: Có một )mất tích ở cuối dòng được đề cập.
jwueller

Cảm ơn, tôi đã sửa câu trả lời của mình. Đó là những gì xảy ra khi tôi gõ quá nhanh và không đọc lại mã của mình.
Alan Geleynse

Bạn phải luôn luôn gọi in_array()với tham số thứ ba được đặt thành true. Kiểm tra tại đây tại sao: stackoverflow.com/questions/37080581/ từ
Andreas

25

nếu mảng của bạn như thế này

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

Dùng cái này

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

thí dụ : 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
Mặc dù mã này có thể trả lời câu hỏi, việc cung cấp ngữ cảnh bổ sung về cách thức và / hoặc lý do giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời.
Vịt Donald

3
6 năm sau, nó đã cho tôi thứ tôi cần. array_column()
NappingRợi

câu trả lời hoàn hảo cho mảng đa chiều
Roshan Sankhe

14

Lớn chức năng, nhưng nó làm việc cho tôi cho đến khi tôi thêm if($found) { break; }vàoelseif

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

Dành cho trẻ em đa chiều: in_array('needle', array_column($arr, 'key'))

Dành cho trẻ em một chiều: in_array('needle', call_user_func_array('array_merge', $arr))


1
Khéo léo! Cảm ơn @ 9ksoft
phaberest

Và không giống như array_column()phương thức, call_user_func_array('array_merge')phương thức này cũng hoạt động với các mảng con dựa trên chỉ mục, +1

6

Bạn luôn có thể tuần tự hóa mảng đa chiều của mình và thực hiện strpos:

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

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

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

Tài liệu khác nhau cho những thứ tôi đã sử dụng:


1
Sai rồi. Hàm của bạn cũng sẽ cho đúng nếu chuỗi tìm kiếm chứa trong một số giá trị mảng (sẽ tìm thấy "Irix" trong "mytoll Irixus").
mdunisch

Tôi đã sửa câu trả lời của mình. @ user3351722

cách này có thể được khắc phục sự cố khi không còn ai (vale duy nhất) và nó là động .. như thế này $ in_arr = (bool) strpose (serialize ($ user_term_was_doaded), 's: 3: "tid"; s: 2: "'. $ Value-> tid.'"; ');
Anees Hikmat Abu Hmiad

2
@ I - II đừng nghĩ bất cứ ai trên Stack Overflow sẽ đăng mã nếu họ không muốn nó được chia sẻ. Hãy sử dụng bất kỳ mã nào trên trang web này cho bất cứ điều gì. Tôi thường thêm một dòng bình luận phía trên đoạn mã có nội dung "Cảm ơn chồng quá mức" và sau đó dán URL tôi tìm thấy mã từ đó.

1
Câu trả lời thú vị, chắc chắn hoạt động trong một số tình huống, nhưng không phải tất cả.
Giải pháp web MKN

4

PHP 5.6, có một giải pháp tốt hơn và rõ ràng hơn cho câu trả lời ban đầu:

Với một mảng đa chiều như thế này:

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

Chúng ta có thể sử dụng toán tử splat :

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

Nếu bạn có khóa chuỗi như thế này:

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

Bạn sẽ phải sử dụng array_valuesđể tránh lỗi Cannot unpack array with string keys:

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

2

Các giải pháp được chấp nhận (tại thời điểm viết bài) bởi 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;
}

Hoàn toàn chính xác nhưng có thể có hành vi ngoài ý muốn khi thực hiện so sánh yếu (tham số $strict = false).

Do cách tung hứng của PHP khi so sánh các giá trị của loại khác nhau

"example" == 0

0 == "example"

Đánh giá true"example"được đúc intvà biến thành 0.

(Xem Tại sao PHP coi 0 bằng với một chuỗi? )

Nếu đây không phải là hành vi mong muốn , có thể thuận tiện để truyền các giá trị số thành chuỗi trước khi thực hiện so sánh không nghiêm ngặt:

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

Đây là chức năng đầu tiên của loại này mà tôi tìm thấy trong hướng dẫn sử dụng php cho in_array . Các chức năng trong các phần bình luận không phải lúc nào cũng tốt nhất nhưng nếu nó không thực hiện được mẹo bạn cũng có thể tìm trong đó :)

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

Giải pháp khó nắm bắt là tốt hơn vì nó chỉ dành cho mảng
Gazillion

1

Đây là đề xuất của tôi dựa trên giải pháp json_encode () với:

  • trường hợp tùy chọn không nhạy cảm
  • trả lại số đếm thay vì đúng
  • bất cứ nơi nào trong mảng (khóa và giá trị)

Nếu không tìm thấy từ, nó vẫn trả về 0 bằng false .

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

Hy vọng nó giúp.


Lưu ý rằng chức năng này cũng khớp với các chuỗi con : ex 00vào 10000hoặc lovào Hello. Hơn nữa sẽ thất bại là kim chứa bất kỳ ký tự json_encodethoát , như dấu ngoặc kép.
Paolo

Tất nhiên nó phụ thuộc vào những gì bạn sẽ làm, nhưng đối với tôi giải pháp này có thực thi nhanh và là đủ.
Meloman

1

Tôi tin rằng bạn chỉ có thể sử dụng mảng_key_exists hiện nay:

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

1

Tôi đang tìm kiếm một hàm cho phép tôi tìm kiếm cả chuỗi và mảng (dưới dạng kim) trong mảng (haystack), vì vậy tôi đã thêm vào câu trả lời của @jwueller .

Đây là mã của tôi:

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

Nó hoạt động quá tạo ra một mảng một chiều mới từ cái ban đầu.

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

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

in_array($needle,$vector);

0

Phiên bản ngắn hơn, dành cho mảng nhiều chiều được tạo dựa trên tập kết quả cơ sở dữ liệu.

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

Sẽ trả về nếu mảng $ os_list chứa 'XP' trong trường os_version.


0

Tôi tìm thấy giải pháp thực sự nhỏ đơn giản:

Nếu mảng của bạn là:

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

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

)

sau đó mã sẽ như sau:

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

0

Tôi đã sử dụng phương pháp này hoạt động cho bất kỳ số lượng lồng nhau và không yêu cầu hack

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

Vui lòng thử:

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

Tôi không chắc chắn về nhu cầu, nhưng điều này có thể làm việc cho yêu cầu của bạn


2
Làm thế nào để tìm kiếm các phím mảng làm bất cứ điều gì? $bCác khóa mảng chỉ là số nguyên ... không có khóa nào được chỉ định trong các mảng này ... và array_keys($b["irix"])sẽ chỉ gây ra lỗi, vì $b["irix"]không tồn tại.
Ben D


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.