2017-05-05 2 views
-1

Ich muss unique urls aus einem Array identifizieren.PHP-Array einzigartig für URLs

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

Ich habe folgende Lösung:

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

Dies ist jedoch nicht sehr effizient O (n^2)

Alle folgenden Varianten sollten als gleich zählen. Kann mir jemand auf eine bessere Lösung hinweisen?

+0

Sie Ihre Frage einmal erklären können? –

+0

@SahilGulati Ich denke, es ist ziemlich klar. Und die Leute verstehen die Frage – Chris

Antwort

1

in_array ist teuer. Erstellen Sie stattdessen einen Hash und speichern Sie die Werte als deren Anzahl. Etwas wie:

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

Und während der Überprüfung, Tun Sie dies:

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

Ich habe es nicht testen, aber vielleicht so etwas funktioniert:

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

Hier ist ein vereinfachte Version. Es verwendet nicht preg_replace, da es viel kostet. Außerdem wird keine unnötige Zeichenfolgenoperation ausgeführt.

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

Eine weitere Performance-Optimierung könnte sich auf die einzigartigen Urls binäre Suche implementieren, weil ‚in_array‘ das gesamte Array suchen, da es nicht sortiert ist.

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

Warum normieren Sie Ihr Ergebnisarray jedes Mal?

hier eine bessere Lösung mit Ihrem Code:

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

Wenn Sie Ihre ursprünglichen Elemente wollen Sie array_keys(array_unique_url($array))

für Ihre normalisierte Urls Sie nicht brauchen array_keys diese verwenden können

0

Versuchen einfachste Lösung. Hier verwenden wir zwei Funktionen preg_replace und parse_url für die Ausgabe

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)); 
Erzielen gewünschten