php массив уникален для URL

Мне нужно определить unique 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). Кто-нибудь может указать мне на лучшее решение?

-1

Решение

in_array это дорого. Вместо этого создайте хеш и сохраните значения как их значения.
Что-то вроде:

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

И во время проверки сделайте следующее:

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

Другие решения

Я не проверял это, но возможно что-то вроде этого будет работать:

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

для ваших нормализованных URL вам не нужно array_keys

0

Попробуйте это самое простое решение. Здесь мы используем две функции preg_replace а также parse_url для достижения желаемого результата

Попробуйте этот фрагмент кода здесь

<?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));
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector