【问题标题】:in_array() and multidimensional arrayin_array() 和多维数组
【发布时间】:2011-05-06 21:54:15
【问题描述】:

我使用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()

【问题讨论】:

  • 接受的解决方案效果很好,但由于 PHP 的类型杂乱,在进行非严格比较时可能会导致意外结果。见:stackoverflow.com/a/48890256/1579327
  • jwueller 的答案和我的答案都是您问题的正确答案。我提出了一个扩展 jwueller 函数的替代解决方案,以避免在进行非严格比较时由于 PHP 的类型杂乱而导致的常见错误。
  • 一个班轮:var_dump(array_sum(array_map(function ($tmp) {return in_array('NT',$tmp);}, $multiarray)) > 0);
  • @AgniusVasiliauskas 聪明的解决方案,但如果第一级数组包含一个不是数组的项目,例如:$multiarray = array( "Hello", array("Mac", "NT"), array("Irix", "Linux"));
  • @Paolo 没有人会阻止您根据需要扩展匿名函数 - 在这种情况下,如果变量 $tmp 是具有 is_array() 函数的数组,则添加检查匿名函数。如果不是数组 - 继续不同的场景。

标签: php arrays multidimensional-array


【解决方案1】:

我发现以下解决方案的代码不是很干净,但它可以工作。它用作递归函数。

function in_array_multi( $needle, $array, $strict = false ) {
  foreach( $array as $value ) { // Loop thorugh all values
    // Check if value is aswell an array
    if( is_array( $value )) {
      // Recursive use of this function
      if(in_array_multi( $needle, $value )) {
        return true; // Break loop and return true
      }
    } else {
      // Check if value is equal to needle
      if( $strict === true ) {
        if(strtolower($value) === strtolower($needle)) {
          return true; // Break loop and return true
        }
      }else {
        if(strtolower($value) == strtolower($needle)) {
          return true; // Break loop and return true
        }
      }
    }
  }

  return false; // Nothing found, false
}

【讨论】:

    【解决方案2】:

    由于 PHP 5.6 有一个更好和更清洁原始答案的解决方案:

    使用这样的多维数组:

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

    我们可以使用splat operator

    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)
    

    【讨论】:

      【解决方案3】:

      我使用这种方法适用于任意数量的嵌套,不需要破解

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

      【讨论】:

        【解决方案4】:

        我找到了非常小的简单解决方案:

        如果你的数组是:

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

        【讨论】:

          【解决方案5】:

          对于多维儿童: in_array('needle', array_column($arr, 'key'))

          对于一维儿童: in_array('needle', call_user_func_array('array_merge', $arr))

          【讨论】:

          • 整洁!谢谢@9ksoft
          • array_column() 方法不同,call_user_func_array('array_merge') 方法也适用于基于索引的子数组,+1
          • 太棒了!我投票支持这个解决方案。
          • 很好,这行得通;并且为了减少开销(如果重要的话),将 array_column($arr, 'key') 隔离到一个命名的静态变量中,因为它基本上是一个名为 'key' 的数字索引数组;
          【解决方案6】:

          这也行。

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

          用法:

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

          【讨论】:

          • 聪明,我喜欢这个。我想知道与foreach 循环相比性能如何。
          • 工作就像一个魅力。
          • 别误会,我喜欢这种方法。但是,当 json_encoding 具有与 $item 匹配的关联键的 $array 时,它将返回误报匹配。更不用说当字符串本身有双引号时可能无意中匹配字符串的一部分。我只会在像这个问题这样的小/简单情况下相信这个功能。
          • 请注意,如果$item 包含破坏preg_match 的第一个参数(正则表达式)的字符,这将失败
          【解决方案7】:

          jwueller

          accepted solution(在撰写本文时)
          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" 被转换为int 并转换为0

          (见Why does PHP consider 0 to be equal to a string?)

          如果这不是所需的行为,在进行非严格比较之前将数值转换为字符串会很方便:

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

          【讨论】:

            【解决方案8】:
            $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';
            }
            

            【讨论】:

            • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
            • 6 年后,它给了我我需要的东西。 array_column()
            • 多维数组的完美答案
            【解决方案9】:

            你可以这样使用

            $result = array_intersect($array1, $array2);
            print_r($result);
            

            http://php.net/manual/tr/function.array-intersect.php

            【讨论】:

              【解决方案10】:

              我正在寻找一个函数,它可以让我在数组 (haystack) 中搜索字符串和数组(如针),所以我添加到 answer by @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;
              }
              

              【讨论】:

                【解决方案11】:

                我相信你现在可以使用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!";
                  }
                ?>
                

                【讨论】:

                  【解决方案12】:

                  这是我的提议基于 json_encode() 解决方案

                  • 不区分大小写选项
                  • 返回计数而不是 true
                  • 数组中的任意位置(键和值)

                  如果没有找到单词,它仍然返回 0 等于 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);
                  }
                  

                  希望对你有帮助。

                  【讨论】:

                  • 请注意,此函数也匹配子字符串:例如 0010000loHello。此外,如果针包含json_encode 转义的任何字符,例如双引号,则会失败。
                  • 当然这取决于你会做什么,但对我来说,这个解决方案执行速度很快,就足够了。
                  【解决方案13】:

                  这样就可以了:

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

                  in_array 仅对一维数组进行操作,因此您需要遍历每个子数组并在每个子数组上运行 in_array

                  正如其他人所指出的,这仅适用于二维数组。如果您有更多嵌套数组,则递归版本会更好。有关示例,请参阅其他答案。

                  【讨论】:

                  • 但是,这只适用于一维。您必须创建一个递归函数才能检查每个深度。
                  • 我运行了代码,但它有一个错误 - Parse error: parse error in C:\wamp\www\000_TEST\php\php.in_array\index.php 在第 21 行 - 这是 if( in_array("Irix", $value) 谢谢。
                  • @lauthiamkok:在上述行的末尾缺少一个)
                  • 谢谢,我修正了我的答案。当我输入太快并且不重新阅读我的代码时,就会发生这种情况。
                  • 您应该始终调用in_array(),并将第三个参数设置为true。在这里查看原因:stackoverflow.com/questions/37080581/…
                  【解决方案14】:

                  如果您知道要搜索哪一列,则可以使用 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';
                  }
                  

                  这个想法在 PHP 手册中 array_search() 的 cmets 部分;

                  【讨论】:

                  • 你也可以试试:in_array('value', array_column($arr, 'active'))
                  • array_column 需要 PHP 5.5+
                  • 本例中是否可以获取到匹配子数组的uid? @ethmz
                  • 这正是我想要的
                  • 找了好久这个解决方案终于完美了!
                  【解决方案15】:

                  您总是可以序列化您的多维数组并执行strpos

                  $arr = array(array("Mac", "NT"), array("Irix", "Linux"));
                  
                  $in_arr = (bool)strpos(serialize($arr),'s:4:"Irix";');
                  
                  if($in_arr){
                      echo "Got Irix!";
                  }
                  

                  我用过的各种文档:

                  【讨论】:

                  • 错了。如果搜索字符串包含在某个数组值中(将在“mytoll Irixus”中找到“Irix”),您的函数也会返回 true。
                  • 我已经修正了我的答案。 @user3351722
                  • 这种方式可以在没有更多人(唯一的vale)时解决问题,并且它是动态的..就像这样 $in_arr = (bool)strpos(serialize($user_term_was_downloaded), 's: 3:"tid";s:2:"'.$value->tid.'";');
                  • @I--我认为如果 Stack Overflow 上的任何人不想共享代码,他们不会发布代码。随意使用本网站上的任何代码做任何事情。我通常在代码 sn-p 上方添加一条注释,上面写着“感谢 Stack Overflow”,然后粘贴我从中找到代码的 URL。
                  • 有趣的答案,在某些情况下肯定有效,但不是全部。
                  【解决方案16】:

                  array_search 呢?根据https://gist.github.com/Ocramius/1290076 ..

                  似乎它比 foreach 快得多
                  if( array_search("Irix", $a) === true) 
                  {
                      echo "Got Irix";
                  }
                  

                  【讨论】:

                  【解决方案17】:

                  较短的版本,用于基于数据库结果集创建的多维数组。

                  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 数组在 os_version 字段中包含“XP”,将返回。

                  【讨论】:

                    【解决方案18】:

                    它也可以首先从原始数组创建一个新的一维数组。

                    $arr = array("key1"=>"value1","key2"=>"value2","key3"=>"value3");
                    
                    foreach ($arr as $row)  $vector[] = $row['key1'];
                    
                    in_array($needle,$vector);
                    

                    【讨论】:

                      【解决方案19】:

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

                      【讨论】:

                      • 谢谢。功能优雅!爱它!谢谢。当我运行你的函数时,我怎么知道它返回 true 或 false,因为我的屏幕没有显示任何内容?谢谢。
                      • 我一直在寻找可以做到这一点的东西,你只是让我免于编写自己的东西 :)
                      • 效果很好。那么我们如何搜索和显示数组键呢?例如:$b = array(1 => array("Mac", "NT"), 3 => array("Irix", "Linux"));
                      • @D.Tate StackOverflow 上的代码在cc by-sa 3.0 下获得许可,需要注明出处(参见页脚)。您可以在此答案的永久链接中添加评论。
                      • @blamb:这是故意的。这就是使函数递归的原因(例如,_r,类似于print_r())。它下降到所有嵌套数组中以搜索该值,直到找不到更多数组为止。通过这种方式,您可以搜索任意复杂度的数组,而不仅仅是两层深度。
                      【解决方案20】:

                      请尝试:

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

                      我不确定是否需要,但这可能适合您的要求

                      【讨论】:

                      • 如何搜索数组键? $b 的数组键只是整数...在这些数组中没有指定的键...而array_keys($b["irix"]) 只会抛出错误,因为$b["irix"] 不存在。
                      【解决方案21】:

                      如果你的数组是这样的

                      $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");

                      【讨论】:

                        【解决方案22】:

                        很棒的功能,但在我将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;
                        }
                        

                        【讨论】:

                          【解决方案23】:

                          这是我在php manual for 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 的解决方案更好,因为它只适用于数组
                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2019-03-31
                          • 2020-04-27
                          • 1970-01-01
                          • 2014-07-26
                          • 2015-07-27
                          相关资源
                          最近更新 更多