【问题标题】:Retain elements in array if associative key starts with specific substring [duplicate]PHP:如何使用键从数组中获取元素
【发布时间】:2012-08-09 15:03:15
【问题描述】:

如果我有这样的数组

array [
       y => 35
       x => 51
       z => 35
       c_3 => 4
       c_1 => 54
       c_6 => 53
       c_9 => 52
] 

我想得到数组

array [c_3=>4, c_1=>54, c_6=>53, c_9=>52]

不要打扰不需要的领域

【问题讨论】:

    标签: php


    【解决方案1】:

    试试这个:

    $filtred = array();
    
    foreach($yourArray as $key => $value)
      if(preg_match('/c_\d/',$key))
        $filtred[] = $value;
    
    print_r($filtred);
    

    【讨论】:

    • 不错的现金解决方案。
    • 我认为 array_filter() 是更好的解决方案。
    【解决方案2】:

    试试这个

     //your array
        $arr1 = array (
               "y" => 35,
               "x" => 51,
               "z" => 35,
               "c_3" => 4,
               "c_1" => 54,
               "c_6" => 53,
               "c_9" => 52
        );
    // Array with keys you want
        $arr2 =  array (
               "c_3" => '',
               "c_1" => '',
               "c_6" => '',
               "c_9" => ''
        );
    //use array_intersect_key to find the common  ;)
        print_r(array_intersect_key($arr1,$arr2));
    

    【讨论】:

    【解决方案3】:

    使用array_filter()检查此解决方案

     $arr = [
       'y' => 35,
       'x' => 51,
       'z' => 35,
       'c_3' => 4,
       'c_1' => 54,
       'c_6' => 53,
       'c_9' => 52,
     ];
    
     $filtered = array_filter($arr, function($v) use($arr){
       return preg_match('#c_\d#', array_search($v, $arr));
     });
    

    以下解决方案适用于 PHP >= 5.6.0

     $filtered = array_filter($arr, function($k){
       return preg_match('#c_\d#', $k);
     }, ARRAY_FILTER_USE_KEY);
    

    两种解决方案都有效,我已经检查过了。

    【讨论】:

      【解决方案4】:

      您可以尝试使用array_filter()

      php documentation page 上有一些有趣的例子。其中之一包括过滤数组键。

      【讨论】:

        【解决方案5】:

        如果您只想选择已知键,请使用 array_slice:http://php.net/manual/en/function.array-slice.php。这里有按键过滤数组的解决方案:PHP: How to use array_filter() to filter array keys?

        【讨论】:

          【解决方案6】:

          我实际上也有类似的问题并在这里寻找答案,但没有什么能真正符合我的期望。

          我想要一些更可重用的东西,可以在我的所有项目中使用,所以我最终编写了这个函数:

              /**
          * Create a new a array containing only the key with a certain $pattern or $subString.
          *
          * Note: You cannot use both $subString and $pattern at once ($substring has precedence on $pattern).
          *
          * @param $errorMessage String to return the error message.
          * @param $source Array in which we must extract data.
          * @param $subString String/Int/Array substring (or array of substring) to seek in the key name.
          * @param $pattern String regex for validating the key.
          * @param $useValueAsKey Boolean if true it will use the value as the key in the new array (scalar values only).
          */
          public static function extractSubArray(&$errorMessage, array &$source, $subString ="", $pattern = "", $useValueAsKey=false){
          
              $newArray = array();
          
              $errorMessage = "";
          
              $dbManager = GeneralDbManager::getInstance();
          
              if (empty($source)){
          
                  $errorMessage = $dbManager->getErrorMessage("SOURCE_ARRAY_IS_EMPTY_ERR", "The array supplied is empty.");
              }
              elseif(empty($subString) and empty($pattern)){
          
                  $errorMessage = $dbManager->getErrorMessage("NO_SUBSTR_OR_PATTERN_ERR", "There are no substring or pattern to match the keys in the array.");
              }
              elseif (!empty($subString) and !(is_string($subString) or is_numeric($subString) or is_array($subString))){
          
                  $errorMessage = $dbManager->getErrorMessage("INVALID_MATCH_SUBSTRING_ERR", "The substring you supplied to match the keys is invalid.");
              }
              elseif(!empty($pattern) and !RegularExpression::testRegex($pattern)){
          
                  $errorMessage = $dbManager->getErrorMessage("INVALID_MATCH_PATTERN_ERR", "The regular expression you supplied to match the keys is invalid.");
              }
              else{
          
                  foreach ($source as $key => $value){
          
                      if (self::isKeyMatchSubstring($key, $subString, $pattern)){
          
                          if ($useValueAsKey and (is_string($value) or is_numeric($value))){
          
                              $newArray[$value] = $value;     
                          }
                          else{
          
                              $newArray[$key] = $value;
                          }
                      }       
                  }
          
                  if (empty($newArray)){
          
                      $errorMessage = $dbManager->getErrorMessage("INVALID_MATCH_PATTERN_ERR", "We were not able to match any keys in the array with the substring or the regular expression.");
                  }
              }
          
              unset($dbManager);
          
              return $newArray;
          }
          
          /**
          * Validate that the $key contains the $substring (string or array) or match the $pattern.
          *
          * @param $key String to validate
          * @param $subString String/Int/Array containing the subString to seek.
          * @param $pattern String regex for validating the key.
          */
          private static function isKeyMatchSubstring($key, $subString, $pattern){
          
              $matched = false;
          
              if (!empty($subString)){
          
                  if (is_string($subString) or is_numeric($subString)){
          
                      if(strpos(strtolower($key), strtolower($subString)) !== false){
          
                          $matched = true;    
                      }
                  }
                  else{ //array
          
                      foreach($subString as $testString){
          
                          $matched = self::isKeyMatchSubstring($key, $testString, "");
          
                          if ($matched){
          
                              break;  
                          }
                      }
                  }   
              }
              elseif(!empty($pattern)){
          
                  $matched = preg_match($pattern, $key);
              }
          
              return $matched;
          }
          

          它使用一个名为 testRegex() 的函数,所以我想我也可以提供该代码:

          /**
          * Make sure that a regular expression works in PHP.
          *
          * @param $regex String the regular expression to validate.
          *
          * @return Boolean
          */
          public static function testRegex($regex){
          
              $isValid = false;
          
              if (!empty($regex) and is_string($regex)){
          
                  if (@preg_match($regex, null) !== false){
                      $isValid = true;
                  }
              }
          
              return $isValid;
          }
          

          当然,没有单元测试的函数会有多好?

              public function testExtractSubArray(){
          
              $errorMessage = "";
          
              $source = array();
          
              //no data
              $this->assertEmpty(Tool::extractSubArray($errorMessage, $source, "", "", false));
          
              $this->assertNotEmpty($errorMessage);
          
              //no substring or pattern
              $source = array(1 => 1);
          
          
              $this->assertEmpty(Tool::extractSubArray($errorMessage, $source, "", "", false));
          
              $this->assertNotEmpty($errorMessage);
          
          
              //invalid substring
              $dbmanager = GeneralDbManager::getInstance();
          
              $this->assertEmpty(Tool::extractSubArray($errorMessage, $source, $dbmanager, "", false));
          
              $this->assertNotEmpty($errorMessage);
          
              unset($dbmanager);
          
          
              //invalid pattern
              $this->assertEmpty(Tool::extractSubArray($errorMessage, $source, "", "[]123", false));
          
              $this->assertNotEmpty($errorMessage);
          
          
              //no match
              $this->assertEmpty(Tool::extractSubArray($errorMessage, $source, "pokemon", "", false));
          
              $this->assertNotEmpty($errorMessage);
          
          
              //valid substring
              $source = array("woot1" => "homer", "woot2" => "bart", "woot3" => "lisa", "doh1" => "marge", "doh2" => "simpson");
          
              $newArray = Tool::extractSubArray($errorMessage, $source, "WOOT", "", false);
          
          
              $this->assertNotEmpty($newArray);
          
              $this->assertEmpty($errorMessage);
          
              $this->assertContains("homer", $newArray);
          
              $this->assertContains("bart", $newArray);
          
              $this->assertContains("lisa", $newArray);
          
              $this->assertNotContains("marge", $newArray);
          
              $this->assertNotContains("simpson", $newArray);
          
          
              //use value as key
              $newArray = Tool::extractSubArray($errorMessage, $source, "WOOT", "", true);
          
          
              $this->assertTrue(array_key_exists("homer", $newArray));
          
              $this->assertTrue(array_key_exists("bart", $newArray));
          
              $this->assertTrue(array_key_exists("lisa", $newArray));
          
          
              //substring array
              $source = array("stan_march" => "normal", "kyle_brofloski" => "jew", "eric_cartman" => "asshole", "kenny_mccormick" => "dead", "butters_stotch" => "pushover");
          
              $newArray = Tool::extractSubArray($errorMessage, $source, array("stan", "kyle", "cartman"), "", false);
          
          
              $this->assertNotEmpty($newArray);
          
              $this->assertEmpty($errorMessage);
          
              $this->assertContains("normal", $newArray);
          
              $this->assertContains("jew", $newArray);
          
              $this->assertContains("asshole", $newArray);
          
              $this->assertNotContains("dead", $newArray);
          
              $this->assertNotContains("pushover", $newArray);
          
          
              //regex
              $source = array("jonathan@woot.ca" => 1, "jonathan" => 2, "12345" => 3, "more $$$" => 4, "$?%$?%$%?" => 5);
          
              $newArray = Tool::extractSubArray($errorMessage, $source, "", RegularExpression::ALPHA_NUMERIC, false);
          
          
              $this->assertNotEmpty($newArray);
          
              $this->assertEmpty($errorMessage);
          
              $this->assertNotContains(1, $newArray);
          
              $this->assertContains(2, $newArray);
          
              $this->assertContains(3, $newArray);
          
              $this->assertNotContains(4, $newArray);
          
              $this->assertNotContains(5, $newArray);
          }
          

          附加说明:此代码使用getErrorMessage() 方法来获取数据库中错误消息的翻译。由于这些错误消息用于调试目的,因此可以直接在代码中硬编码以提高性能(无需实例化类来获取错误消息并打开与数据库的连接)。

          嗯,我希望它能帮助像我这样的可重用狂。

          来自蒙特利尔的Jonathan Parent-Lévesque

          【讨论】:

            【解决方案7】:

            我已经尝试了上述解决方案,但上述解决方案在 PHP 5.6 中均不适合我

            所以,我尝试并使用了对我有用的不同解决方案...

            $subArray = array();
            
            foreach($arryDetails as $key => $value)
              if(preg_match('/^c_/',$key))
                $subArray[$key] = $value;
            
            print_r($subArray);
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-01-17
              • 2019-12-17
              • 2019-12-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多