【问题标题】:PHP sort list of subdomains by domainPHP按域排序子域列表
【发布时间】:2018-08-09 07:20:55
【问题描述】:

我有一个域列表(数组)

sub1.dom1.tld1
sub2.dom2.tld2
sub1.sub2.dom1.tld1
sub3.dom1.tld3

我想实现以下目标:

dom1.tld1
-> sub1.dom1.tld1
-> sub2.dom1.tld1
--> sub1.sub2.dom1.tld1

dom2.tld2
-> sub2.dom2.tld2

dom1.tld3
-> sub3.dom1.tld3

我已经尝试过调整它,但它并不适合:

How to alphabetically sort a php array after a certain character in a string

我将不胜感激。

【问题讨论】:

    标签: php arrays sorting


    【解决方案1】:

    我以前也曾患过类似的头痛。在短期内,我会翻转域组件的顺序并在表/视图中使用隐藏的排序列: $sortstring = implode('.',array_reverse(explode('.', $domain)));

    从长远来看,我在将对数据库的更改保存到计算字段/列之前保存了域记录的反向格式,这样每次查看域列表时都不必重新计算。

    如果您不想要那个子域,只需在翻转后删除数组的最后一个元素......

    【讨论】:

    • 这实际上是个好主意,而不是通过创建复杂的数组排序来浪费计算能力,只需将所有内容添加到计算列中并使用该列进行排序/分组
    【解决方案2】:

    你可以这样继续:

    $array=array(
    'sub1.dom1.tld1',
    'sub2.dom2.tld2',
    'sub1.sub2.dom1.tld1',
    'sub2.sub2.dom1.tld1',
    'sub3.sub2.dom1.tld1',
    'sub3.dom1.tld3');
    
    function cmp($a,$b){
        $a=array_reverse(explode('.',$a));
        $b=array_reverse(explode('.',$b));
        $ca=count($a);
        $cb=count($b);
        $string='';;
        for($i=0,$c=min($ca,$cb);$i<$c;$i++){
            $result=strnatcmp($a[$i],$b[$i]);
            if($result!==0) return $result;
    
        }
        return $result;
    }
    
    usort($array,'cmp');
    print_r($array);
    

    输出是:

    Array
    (
        [0] => sub1.dom1.tld1
        [1] => sub1.sub2.dom1.tld1
        [2] => sub2.sub2.dom1.tld1
        [3] => sub3.sub2.dom1.tld1
        [4] => sub2.dom2.tld2
        [5] => sub3.dom1.tld3
    )
    

    【讨论】:

    • @gavu 这个当然是使用数组排序的方式,但是代码没有那么复杂。它也是通用的,可以和真实的域和子域数组一起使用。
    【解决方案3】:

    这是一种类似于@Elementary 答案结合@CBO one 的方法:

    $domains = [
        'sub.bbb.com',
        'www.aaa.com',
        '*.zzz.com',
        'aaa.com',
        '*.sub.bbb.com',
        'zzz.com',
        'beta.bbb.com',
        'bbb.com',
        'aaa.fr',
    ];
    
    
    // @see https://stackoverflow.com/a/61461912/1731473
    $computeDomainToSort = static function (string $domain): string {
        return \implode(
            '.',
            array_reverse(
                explode('.', $domain,
                    // Keep the base domain.tld collapsed for comparison.
                    substr_count($domain, '.')
                )
            )
        );
    };
    
    \usort($this->domains, static function (string $domain1, string $domain2) use ($computeDomainToSort): int {
        $domain1 = $computeDomainToSort($domain1);
        $domain2 = $computeDomainToSort($domain2);
    
        return strnatcmp($domain1, $domain2);
    });
    

    这样,给定的域将按如下方式排序:

    aaa.com
    www.aaa.com
    aaa.fr
    bbb.com
    beta.bbb.com
    sub.bbb.com
    *.sub.bbb.com
    zzz.com
    *.zzz.com
    

    主要区别在于 $computeDomainToSort lambda 函数,我将基础 domain.tld 保留在一个片段上以进行更自然的排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 2019-07-18
      • 2010-12-21
      • 2013-01-07
      • 1970-01-01
      • 2020-11-24
      相关资源
      最近更新 更多