Php 如何以这种方式按字母顺序排列域列表?

Php 如何以这种方式按字母顺序排列域列表?,php,Php,因此,如果我想按字母顺序组织一个网站列表,并且有所有这些表单: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.

因此,如果我想按字母顺序组织一个网站列表,并且有所有这些表单: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
然而,这不是我想要的字母顺序。我希望它们按域字母顺序排列,然后按子域字母顺序排列为“分界线”,换句话说,如下所示:

a.domain.com
anotherdomain.com
domain.com
anotherdomain.com
domain.com
a.domain.com

有人能告诉我如何编写PHP(或JavaScript)来实现这一点吗?(您可以假设每个“网站”都在一行新的代码上。)

如果提供的所有参数都是这种形式(并且在
.com
之后没有其他信息),您可以使用
分解('.','a.domain.com')
然后您可以根据分解结果的倒数第二项对项目进行排序

$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
)
*/
编辑:

根据Alnitak的建议,下面是一个版本的
sort\u 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;
    }
}

请注意,这对于小列表很有效,但对于大列表则效率很低,因为分解和反转步骤针对的是每个比较,而不仅仅是每个元素。对于大列表,请先对数据集进行标准化,以实现最佳比较,然后进行排序,然后再转换回所需格式。或者,请记住e的标准化版本第一次遇到ach键。你不知道我有多喜欢上面的解决方案:编辑的解决方案。:)竖起大拇指!