2017-05-05 22 views
-1

我需要從數組中識別unique urlsphp array對於urls唯一

以下所有變體,都應視爲等於:

http://google.com 
https://google.com 
http://www.google.com 
https://www.google.com 
www.google.com 
google.com 

我有以下溶液:

public static function array_unique_url(array $array) : array 
{ 
    $uniqueArray = []; 
    foreach($array as $item) { 
     if(!self::in_array_url($item, $uniqueArray)){ 
      $uniqueArray[] = $item; 
     } 
    } 
    return $uniqueArray; 
} 

public static function in_array_url(string $needle, array $haystack): bool { 
    $haystack = array_map([self::class, 'normalizeUrl'], $haystack); 
    $needle = self::normalizeUrl($needle); 

    return in_array($needle, $haystack); 
} 

public static function normalizeUrl(string $url) { 
    $url = strtolower($url); 
    return preg_replace('#^(https?://)?(www.)?#', '', $url); 
} 

然而,這不是很有效爲O(n^2)。任何人都可以指出我更好的解決方案嗎?

+0

你能解釋一下你的問題一次? –

+0

@SahilGulati我認爲這很清楚。人們理解這個問題 – Chris

回答

1

in_array是昂貴的。而不是這樣做創建一個散列和存儲值作爲他們的計數。 喜歡的東西:

$myHash = []; //a global array to hold values. 

雖然檢查,這樣做:

if(!empty($myHash[$needle])){ 
    //already exits 
} 
0

我沒有測試它,但也許這樣的事情會工作:

function getUniqueUrls(array $urls) 
{ 
    $unique_urls = []; 
    foreach ($urls as $url) { 
     $normalized_url = preg_replace('#^(https?://)?(www.)?#', '', strtolower($url)); 
     $unique_urls[$normalized_url] = true; 
    } 

    return array_keys($unique_urls); 
} 

$arr = [ 
    'http://google.com', 
    'https://google.com', 
    'http://www.google.com', 
    'https://www.google.com', 
    'www.google.com', 
    'google.com' 
]; 

$unique_urls = getUniqueUrls($arr); 
0

這裏是一個簡化版本。它不使用preg_replace,因爲它花費了很多。它也不會做任何不必要的字符串操作。

$urls = array(
    "http://google.com", 
    "https://google.com", 
    "http://www.google.com", 
    "https://www.google.com", 
    "www.google.com", 
    "google.com" 
); 

$uniqueUrls = array(); 

foreach($urls as $url) { 
    $subPos = 0; 
    if(($pos = stripos($url, "://")) !== false) { 
     $subPos = $pos + 3; 
    } 
    if(($pos = stripos($url, "www.", $subPos)) !== false) { 
     $subPos = $pos + 4; 
    } 
    $subStr = strtolower(substr($url, $subPos)); 
    if(!in_array($subStr, $uniqueUrls)) { 
     $uniqueUrls[] = $subStr; 
    } 
} 

var_dump($uniqueUrls); 

另一個性能優化可實現的唯一URL二進制搜索,因爲「in_array」搜索整個陣列,因爲它是沒有排序。

0
<?php 

$urls = [ 
    'http://google.com', 
    'https://google.com', 
    'http://www.google.com', 
    'https://www.google.com', 
    'www.google.com', 
    'google.com', 
    'testing.com:9200' 
]; 

$uniqueUrls = []; 

foreach ($urls as $url) { 
    $urlData = parse_url($url); 
    $urlHostName = array_key_exists('host',$urlData) ? $urlData['host'] : $urlData['path']; 
    $host = str_replace('www.', '', $urlHostName); 
    if(!in_array($host, $uniqueUrls) && $host != ''){ 
     array_push($uniqueUrls, $host); 
    } 
} 
print_r($uniqueUrls); 

?> 
0

爲什麼你每次都調整結果數組?

這裏是你的代碼更好的解決方案:

public static function array_unique_url(array $array): array 
{ 
    $uniqueArray = []; 
    foreach ($array as $item) { 
     if (!isset($uniqueArray[$item])) { 
      $uniqueArray[$item] = self::normalizeUrl($item); 
     } 
    } 

    return $uniqueArray; 
} 

public static function normalizeUrl(string $url) 
{ 
    return preg_replace('#^(https?://)?(www.)?#', '', strtolower($url)); 
} 

如果你希望你的原始項目可以使用array_keys(array_unique_url($array))

你的歸一化的網址,你不需要array_keys

0

試試這個最簡單的解決方案這裏我們使用兩個函數preg_replaceparse_url以實現所需的輸出

Try this code snippet here

<?php 

$urls = array(
    "http://google.com", 
    "https://google.com", 
    "http://www.google.com", 
    "https://www.google.com", 
    "www.google.com", 
    "google.com" 
); 

$uniqueUrls=array(); 
foreach($urls as $url) 
{ 
    $changedUrl= preg_replace("/^(https?:\/\/)?/", "http://", $url);//adding http to urls which does not contains. 
    $domain= preg_replace("/^(www\.)?/","",parse_url($changedUrl,PHP_URL_HOST));//getting the desired host and then removing its www. 
    preg_match("/^[a-zA-Z0-9]+/", $domain,$matches);//filtering on the basis of domains 
    $uniqueUrls[$matches[0]]=$domain; 
} 
print_r(array_values($uniqueUrls));