我有一个域列表(数组)
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
我将不胜感激。
答案 0 :(得分:1)
我以前不得不经历过类似的头痛。在短期内,我会翻转域组件的顺序,并在表/视图中使用隐藏的排序列:
$sortstring = implode('.',array_reverse(explode('.', $domain)));
从长远来看,在将对数据库的更改保存到计算的字段/列中之前,我保存了域记录的相反格式,这样就不必在每次查看域列表时都重新计算它。
如果您不想要该子域,只需在翻转后删除数组的最后一个元素即可。...
答案 1 :(得分:0)
您可以这样进行:
$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
)
答案 2 :(得分:0)
这是一种类似于@Elementary答案的方法,结合到@CBO一个:
$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
保留在一块上,以进行更自然的排序。