Mohammad Umer
Mohammad Umer

Reputation: 534

Filter just duplicate urls from an php array

Here is an 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 
   [Em Debt] => http://globalevolution.gws.fcnws.com/fs_Overview.html?isin=LU0501220262 
) 

If I use array_unique() it will filter Will be launched shortly from the array also.

I just want to filter duplicate urls, not text.

UPDATE:

I need to be Array order remain as same, Just filter dupl

Upvotes: 10

Views: 880

Answers (5)

Mohammad Umer
Mohammad Umer

Reputation: 534

Okay here is I got the answer

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

Here is array sub sort function code.

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

Upvotes: 3

mickmackusa
mickmackusa

Reputation: 47874

If you want to modify the input array, not generate a new filtered array, you can use strpos() to identify urls, a lookup array to identify duplicate urls, and unset() to modify the array.

  • strpos($v,'http')===0 not only requires http to be in the string, it requires it to be the first four characters in the string. To be clear, this accommodates https as well. strstr() and substr() will always be less efficient than strpos() when simply checking the existence or position of a substring. (The second note @ PHP Manual's strstr() boasts of the benefits of using strpos() when merely checking the existence of a substring.)
  • Using iterated in_array() calls to check the $lookup array, is less efficient than storing the duplicate urls as keys in the lookup array. isset() will outperform in_array() every time. (Reference Link)
  • The OP's sample input does not indicate that there are any monkey-wrenching values that will start with http yet not be a url, nor non-urls that start with http. For this reason, strpos() is a suitable and lightweight function call. If trouble-making urls are possible, then sevavietl's url validation is a more reliable function call. (PHP Manual Link)
  • From my online performance tests, my answer is the fastest method posted which provides the desired output array.

Code: (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);

Output:

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

Just for fun, a functional/unorthodox/convoluted method can look like this (not recommended, purely a demonstration):

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

Upvotes: 3

LF-DevJourney
LF-DevJourney

Reputation: 28529

You can traverse the array one time to get the result, in this process you need to use an extra array to indicate which url you have saved in the result.

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

Upvotes: 5

sevavietl
sevavietl

Reputation: 3802

Well, you can use 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;
});

Here is demo.

Upvotes: 7

pravindot17
pravindot17

Reputation: 1273

Here is your answer:

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

Upvotes: 5

Related Questions