Reputation: 534
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
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
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.)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)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)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
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
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
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