【问题标题】:Filter just duplicate urls from an php array仅从 php 数组中过滤重复的 url
【发布时间】:2018-05-22 17:34:39
【问题描述】:

这是一个数组

Array ( 
   [EM Debt] => http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0616502026&culture=en-GB 
   [EM Local Debt] => Will be launched shortly 
   [EM Blended Debt] => Will be launched shortly 
   [Frontier Markets] => http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0501220262 
   [Absolute Return Debt and FX] => Will be launched shortly 
   [Em Debt] => http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0501220262 
) 

如果我使用array_unique(),它也会从数组中过滤Will be launched shortly

我只想过滤重复的网址,而不是文本。

更新:

我需要数组顺序保持不变,只过滤重复

【问题讨论】:

    标签: php arrays url duplicates filtering


    【解决方案1】:

    好的,我知道答案了

    $urls = ( [EM Debt] => http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0616502026&culture=en-GB 
    [EM Local Debt] => Will be launched shortly 
    [EM Blended Debt] => Will be launched shortly 
    [Frontier Markets] => http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0501220262 [Absolute Return Debt and FX] => Will be launched shortly [Em Debt] => http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0501220262 );
    
    $url_array = [];
    foreach($urls as $title => $url) {
        if(strpos($url, 'http://') !== false) {
            $url_array[$title] = $url;
        } else {
            $string_array[$title] = $url;
        }
        $keys[] = $title;
    }
    
    $url_array = array_unique($url_array);
    $urls = array_merge($url_array, $string_array);
    $urls = array_sub_sort($urls, $keys);
    

    这里是数组子排序功能代码。

    function array_sub_sort(array $values, array $keys){
        $keys = array_flip($keys);
        return array_merge(array_intersect_key($keys, $values), array_intersect_key($values, $keys));
    }
    

    【讨论】:

      【解决方案2】:

      如果要修改输入数组,而不是生成新的过滤数组,可以使用strpos()标识url,lookup数组标识重复url,unset()修改数组。

      • strpos($v,'http')===0 不仅要求 http 在字符串中,还要求它是字符串中的前四个字符。需要明确的是,这也适用于https。在简单地检查子字符串的存在或位置时,strstr()substr() 的效率总是低于strpos()。 (第二个注释 @PHP Manual's strstr() 夸耀在仅检查子字符串是否存在时使用 strpos() 的好处。)
      • 使用迭代的in_array() 调用来检查$lookup 数组的效率低于将重复的url 作为键存储在查找数组中。 isset() 每次都会胜过 in_array()。 (Reference Link)
      • OP 的示例输入并未表明存在任何以http 开头但不是url 的猴子值,也不是以http 开头的非url。因此,strpos() 是一个合适且轻量级的函数调用。如果麻烦的 url 是可能的,那么 sevavietl 的 url 验证是一个更可靠的函数调用。 (PHP Manual Link)
      • 根据我的在线性能测试,我的答案是提供所需输出数组的最快方法。

      代码:(Demo)

      $array=[
          'EM Debt'=>'http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0616502026&culture=en-GB',
          'EM Local Debt'=>'Will be launched shortly',
          'EM Blended Debt'=>'Will be launched shortly',
          'Frontier Markets'=>'http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0501220262',
          'Absolute Return Debt and FX'=>'Will be launched shortly',
          'Em Debt'=>'http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0501220262'
      ];
      
      foreach($array as $k=>$v){
          if(isset($lookup[$v])){          // $v is a duplicate
              unset($array[$k]);           // remove it from $array
          }elseif(strpos($v,'http')===0){  // $v is a url (because starts with http or https)
              $lookup[$v]='';              // store $v in $lookup as a key to an empty string
          }
      }
      var_export($array);
      

      输出:

      array (
        'EM Debt' => 'http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0616502026&culture=en-GB',
        'EM Local Debt' => 'Will be launched shortly',
        'EM Blended Debt' => 'Will be launched shortly',
        'Frontier Markets' => 'http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0501220262',
        'Absolute Return Debt and FX' => 'Will be launched shortly',
      )
      

      只是为了好玩,函数式/非正统/复杂的方法可能看起来像这样(不推荐,纯粹是演示):

      var_export(
          array_intersect_key(
              $array,                                    // use $array to preserve order
              array_merge(                               // combine filtered urls and unfiltered non-urls
                  array_unique(                          // remove duplicates
                      array_filter($array,function($v){  // generate array of urls
                          return strpos($v,'http')===0;
                      })
                  ),
                  array_filter($array,function($v){  // generate array of non-urls
                      return strpos($v,'http')!==0;
                  })
              )
          )
      );
      

      【讨论】:

      • 根据您的谓词 (strpos($v,'http')===0),“http 是世界上最好的协议”被视为 URL。
      • 我很确定我称赞了你的方法。我不确定你想对我做什么。
      • 感谢您的夸奖。我虽然这个网站的目的是讨论解决方案以找到最好的(包括指出陷阱)。对不起,如果我的评论以任何方式冒犯了您。
      【解决方案3】:

      你可以遍历数组一次得到结果,在这个过程中你需要使用一个额外的数组来表明你在结果中保存了哪个url。

      $saved_urls = [];
      $result = [];
      foreach($array as $k => $v)
      {
          if('http://' == substr(trim($v), 0, 7) || 'https://' == substr(trim($v), 0, 8))
          {
              if(!isset($saved_urls[$v]))    // check if the url have saved
              {
                  $result[$k] = $v;
                  $saved_urls[$v] = 1;
              }
          }else
              $result[$k] = $v;
      }
      

      【讨论】:

      • 如果链接使用https怎么办?
      • @sevavietl 你是对的。我错过了https 案例。
      【解决方案4】:

      嗯,你可以使用array_filter

      $filtered = array_filter($urls, function ($url) {
          static $used = [];
      
          if (filter_var($url, FILTER_VALIDATE_URL)) {
              return isset($used[$url]) ? false : $used[$url] = true;
          }
      
          return true;
      });
      

      这里是demo

      【讨论】:

      • + 用于您的 filter_var 和 cmets。
      • 恭喜。为了完整起见,您可能需要在答案中添加解释。
      【解决方案5】:

      这是你的答案:

      <?php
      // taking just example here, replace `$array` with yours
      $array = ['http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0616502026&culture=en-GB', 'abc', 'abc', 'http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0616502026&culture=en-GB'];
      $url_array = [];
      foreach($array as $ele) {
          if(strpos($ele, 'http://') !== false) {
              $url_array[] = $ele;
          } else {
              $string_array[] = $ele;
          }
      }
      
      $url_array = array_unique($url_array);
      print_r(array_merge($string_array, $url_array));
      ?>
      

      【讨论】:

      • 我们可以保持数组的顺序只过滤重复的url吗?
      • 因为我们再次合并,数组的顺序被打乱了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      • 2016-12-30
      • 2016-05-27
      • 2018-12-07
      • 1970-01-01
      • 2016-01-08
      相关资源
      最近更新 更多