有没有人实现对域名列表进行排序?
我已经看到一些应用程序将它们排序为扁平字符串,但问题是您最终将所有相关主机分散在域中:
a.me.com a.you.com b.me.com b.you.com
所以,我想出的基本逻辑是把标签的顺序倒过来,然后排序。
一个标签的 FQDN 应被视为主机名,并且可能单独排序,可能位于顶部。
理想情况下,我正在寻找 javascript 和 java 版本。
我也不知道这种设计是否适用于较新的国际化域名。
有没有人实现对域名列表进行排序?
我已经看到一些应用程序将它们排序为扁平字符串,但问题是您最终将所有相关主机分散在域中:
a.me.com a.you.com b.me.com b.you.com
所以,我想出的基本逻辑是把标签的顺序倒过来,然后排序。
一个标签的 FQDN 应被视为主机名,并且可能单独排序,可能位于顶部。
理想情况下,我正在寻找 javascript 和 java 版本。
我也不知道这种设计是否适用于较新的国际化域名。
我不特别了解 Java 和 Javascript,但是许多语言提供了某种可以按字典顺序排序的数组数据结构。所以,就像你说的,将“a.example.com”转换成{“com”,“example”,“a”},然后让默认的排序规则运行。然后,字典排序将完全按照您的意愿进行。
如果您有本地域和 FQDN 的列表,我同意您希望将它们分开。任何没有句号的东西都可以先被过滤掉。或者,您可以将这些全部解析为 FQDN,然后对整个列表进行排序。
一些执行此操作的 Python 代码(应该非常接近地映射到 Javascript):
hosts = ["a.foo.com", "b.foo.com", "foo.com", "c.bar.com"]
split_hosts = []
for h in hosts:
segments = h.split('.')
segments.reverse()
split_hosts.append(segments)
split_hosts.sort()
for segments in split_hosts:
segments.reverse()
print ".".join(segments)
这打印:
c.bar.com
foo.com
a.foo.com
b.foo.com
根据汤姆的回答...
hosts = new Array( "a.foo.com", "b.foo.com", "foo.com", "c.bar.com" );
//print("Unsorted:");
//for (host in hosts )
// print(hosts[host]);
sorted_hosts = new Array();
split_hosts = new Array();
for(h in hosts)
{
segments = hosts[h].split('.');
segments.reverse();
split_hosts.push(segments);
}
split_hosts.sort()
for(h in split_hosts)
{
split_hosts[h].reverse()
sorted_hosts.push(split_hosts[h].join("."))
}
//print("Sorted:");
//for (host in sorted_hosts )
// print(sorted_hosts[host]);
打印语句在SquareFree JavaScript 开发环境中工作(未注释时),这是一个测试 javascript 片段的方便场所......
这是 80 年代初的 big-endian vs little-endian 战争的结果,little-endian 团队获胜。在英国,域名最初的排序类似于(假设的)“uk.ac.leeds”,用于英国“学术”(University of Leeds)。这是大端排序 - 让您的排序更容易。这也使得在 URL 中欺骗互联网站点变得更加困难。当然,现在的顺序是 little-endian,假设的 URL 是“leeds.ac.uk”。
要将相关域名合理地排序在一起,您必须先实现按最右边的组件(.com、.uk、.org)排序的效果,然后再下一个左边,然后重复......换句话说(如@Bala说),您将不得不做一些类似于拆分名称并从右到左排序的事情。
这是在 Perl 中的实现方式:
#!/usr/bin/perl -w
use strict;
my @hosts = qw(
bar.org
a.foo.com
b.foo.com
foo.com
c.bar.com
);
print join("\n", sort {
$a = lc($a);
$b = lc($b);
if ($a eq $b) {
return 0;
}
my @a = reverse(split(/\./, $a));
my @b = reverse(split(/\./, $b));
my $max = (scalar(@a), scalar(@b))[@a < @b];
for (my $i=0; $i < $max; $i++) {
if (($i < @a) && ($i < @b)) {
if (my $c = $a[$i] cmp $b[$i]) {
return $c;
}
}
else {
return scalar(@a) <=> scalar(@b);
}
}
return 0;
} @hosts) . "\n";
您可以将域名拆分为单独的字段并进行连续排序。您可以创建一个包含三个字段的域名对象,并创建一个要排序的域名列表。对三个字段中的每一个进行排序。最后,您将获得一个包含相关主机的域名排序列表。
我想出了这个利用 Array.prototype.sort() 和 ES6 生成器的解决方案:
function* reverseIterateParts(domain) {
let currentEnd = domain.length;
for (let index = currentEnd-1; index >= -1; index--) {
if (index == -1 || domain[index] == '.') {
yield domain.substring(index + 1, currentEnd);
currentEnd = index;
}
}
}
arrayOfDomainNames.sort((domainA, domainB) => {
let partsOfA = reverseIterateParts(domainA);
let partsOfB = reverseIterateParts(domainB);
while (true) {
let partA = partsOfA.next();
let partB = partsOfB.next();
if (partA.done) {
if (partB.done) {
return 0;
}
return -1;
}
if (partB.done) {
return 1;
}
if (partA.value > partB.value) {
return 1;
}
if (partA.value < partB.value) {
return -1;
}
}
});