2011-04-11 111 views
7

因此,如果我想按字母顺序组织网站列表,并且存在以下所有格式:example1.com,test.com,stackoverflow.com,google.com,那很容易。不过,我也想组织子域名。考虑以下三个领域:如何以这种方式字母表的域名列表?

a.domain.com 
domain.com 
anotherdomain.com 

如果我把他们交给软件按字母顺序排列,他们会按字母顺序排列如下:

a.domain.com 
anotherdomain.com 
domain.com 

然而,这不是我多么希望他们按字母顺序排列。我希望他们能够通过域换句话说地按字母顺序排列,然后通过子域的“抢七”,像这样:

anotherdomain.com 
domain.com 
a.domain.com 

有人能告诉我如何编写PHP(或JavaScript)来做到这一点? (你可以假设每一个“网站”上的代码,一个新的行。)

回答

7
$array = array(
    'b.domain.com', 
    'a.domain.com', 
    'domain.com', 
    'anotherdomain.com', 
    'php.net', 
    'example.com' 
); 

function sort_domains($domain1, $domain2) 
{ 
    $domain1 = array_reverse(explode('.', $domain1)); 
    $domain2 = array_reverse(explode('.', $domain2)); 
    // set $i to 0 if you want the TLD to be sorted 
    for($i = 1; ; $i++) 
    { 
     // Might be a good idea to store the value of the issets up here 
     if(isset($domain1[$i]) && isset($domain2[$i])) 
     { 
      $difference = strcmp($domain1[$i], $domain2[$i]); 
      if($difference != 0) 
      { 
       return $difference; 
      } 
      continue; 
     } 
     if(!isset($domain1[$i]) && !isset($domain2[$i])) 
     { 
      return 0; 
     } 
     return isset($domain1[$i]) ? 1 : -1; 
    } 
} 

usort($array, 'sort_domains'); 

/* 
Array 
(
    [0] => anotherdomain.com 
    [1] => domain.com 
    [2] => a.domain.com 
    [3] => b.domain.com 
    [4] => example.com 
    [5] => php.net 
) 
*/ 

编辑:

按参宿一的建议,这里是sort_domains一个版本,缓存每个域​​的碎片名称:

function sort_domains($domain1, $domain2) 
{ 
    static $cache = array(); 
    if(!array_key_exists($domain1, $cache)) 
    { 
     $cache[$domain1] = array_reverse(explode('.', $domain1)); 
    } 
    if(!array_key_exists($domain2, $cache)) 
    { 
     $cache[$domain2] = array_reverse(explode('.', $domain2)); 
    } 
    // set $i to 0 if you want the TLD to be sorted 
    for($i = 1; ; $i++) 
    { 
     $isset_1 = isset($cache[$domain1][$i]); 
     $isset_2 = isset($cache[$domain2][$i]); 
     if($isset_1 && $isset_2) 
     { 
      $difference = strcmp($cache[$domain1][$i], $cache[$domain2][$i]); 
      if($difference != 0) 
      { 
       return $difference; 
      } 
      continue; 
     } 
     if(!$isset_1 && !$isset_2) 
     { 
      return 0; 
     } 
     return $isset_1 ? 1 : -1; 
    } 
} 
+2

请注意,这对于小列表来说工作得很好,但对于大型列表来说效率很低,因为爆炸和反向步骤是针对每个_comparison_而不是每个元素完成的。对于大型列表,将数据集标准化以便首先进行最佳比较,然后进行排序,然后再转换回所需的格式。 – Alnitak 2011-04-11 16:47:24

+0

或者,在第一次遇到每个键时记忆每个键的标准化版本。 – Alnitak 2011-04-11 16:50:37

+0

你不知道我有多喜欢上面的解决方案:编辑过的。 :) 竖起大拇指! – Cogicero 2011-04-11 17:15:17

1

如果提供的所有参数都是这种形式的(并有.com后,没有其他信息,你可以使用explode('.', 'a.domain.com')然后你就可以排序根据第二次的爆炸结果的最后一个项目的项目

相关问题