1

有没有人实现对域名列表进行排序?

我已经看到一些应用程序将它们排序为扁平字符串,但问题是您最终将所有相关主机分散在域中:

a.me.com a.you.com b.me.com b.you.com

所以,我想出的基本逻辑是把标签的顺序倒过来,然后排序。

一个标签的 FQDN 应被视为主机名,并且可能单独排序,可能位于顶部。

理想情况下,我正在寻找 javascript 和 java 版本。

我也不知道这种设计是否适用于较新的国际化域名。

4

6 回答 6

2

我不特别了解 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
于 2008-12-05T01:38:23.957 回答
2

根据汤姆的回答...


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 片段的方便场所......

于 2008-12-05T02:50:55.603 回答
1

这是 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说),您将不得不做一些类似于拆分名称并从右到左排序的事情。

于 2008-12-05T01:31:07.840 回答
1

这是在 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";
于 2011-01-24T19:02:28.140 回答
0

您可以将域名拆分为单独的字段并进行连续排序。您可以创建一个包含三个字段的域名对象,并创建一个要排序的域名列表。对三个字段中的每一个进行排序。最后,您将获得一个包含相关主机的域名排序列表。

于 2008-12-05T01:24:00.583 回答
0

我想出了这个利用 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;
        }
    }
});
于 2017-05-18T17:05:56.850 回答