Der Schlüssel zur effizienten Sortierung in Perl besteht darin, eine Funktion zu erstellen, die den zu sortierenden Wert in eine repräsentative Zeichenfolge umwandelt, die lexikografisch sortiert werden kann. Wenn Sie beispielsweise Datumsangaben sortieren möchten, können Sie sie in das Format yyyymmdd
umwandeln. In diesem Fall werden wir die Teile der Domäne neu anordnen, so dass
foo.bar.apple1.co.uk
eine der folgenden Aktionen wird:
# Using this approach, the sorted order of apple1.com and apple1.net will vary.
apple1.bar.foo
# Using this approach, the sorted order of apple1.com and apple1.net will be consistent.
apple1.bar.foo<NUL>uk.co
Wir wollen die Zahlen Art zu sein natürlich, (1, 2, 10 und nicht 1, 10, 2). Unsere Schlüsselfunktion könnte damit umgehen, aber wir nehmen den einfachen Ausweg, indem wir sort
durch natkeysort
von Sort::Key::Natural ersetzen. Als Bonus, natkeysort
können wir einfach unsere Schlüsselfunktion integrieren!
Der schwierige Teil ist, das Suffix zu identifizieren. Es gibt keine Regel dafür, nur ständig ändernde Definitionen. Daher verwenden wir ein Modul, um das Suffix zu identifizieren.
die Tastenfunktion implementiert Verwendung Domain::PublicSuffix:
use feature qw(state);
use Domain::PublicSuffix qw();
sub get_sort_key {
my ($host) = @_;
$host =~ s/\.\z//;
state $dps = Domain::PublicSuffix->new();
$dps->get_root_domain($host)
or die "$host: ".$dps->error();
my @name = split /\./, substr($host, 0, -length($dps->suffix())-1);
my @suffix = split /\./, $dps->suffix();
return join('.', reverse @name)."\0".join('.', reverse @suffix);
}
die Tastenfunktion implementiert Verwendung IO::Socket::SSL::PublicSuffix:
use feature qw(state);
use IO::Socket::SSL::PublicSuffix qw();
sub get_sort_key {
my ($host) = @_;
my @host = split(/\./, $host);
state $ps = IO::Socket::SSL::PublicSuffix->default();
my ($name, $suffix) = $ps->public_suffix(\@host);
return join('.', reverse @$name)."\0".join('.', reverse @$suffix);
}
Die obigen Funktionen werden wie folgt verwendet:
use feature qw(say);
use Sort::Key::Natural qw(natkeysort);
my @hosts = (
'www.apple3.net',
'www.apple3.com',
'this.apple4.com',
'that.apple4.com',
'www.apple10.com',
'that.apple1.uk',
'and.that.apple2.com.br',
);
my @sorted_hosts = natkeysort { get_sort_key($_) } @hosts;
say for @sorted_hosts;
Ausgang:
that.apple1.uk
and.that.apple2.com.br
www.apple3.com
www.apple3.net
that.apple4.com
this.apple4.com
www.apple10.com
IO::Socket::SSL::PublicSuffix angeblich wird häufiger aktualisiert als Domain::PublicSuffix (und Mozilla::PublicSuffix), aber es Teil eines größeren Distro ist.
Also ist 'apple2.com.br' eine Subdomain? Welche Regel verwenden Sie, um zu entscheiden, welcher Unterdomäne-Teil des Domänennamens verwendet wird? –
Aktuelle Versionen des IO :: Socket :: SSL-Moduls enthalten [IO :: Socket :: SSL :: PublicSuffix] (https: // metacpan.org/pod/IO :: Socket :: SSL :: PublicSuffix), mit dem Sie das öffentliche Suffix (zB 'com.br') oder die Root-Domain (eine Ebene höher, zB' apple2.com.br') erhalten können zu einer Domain. Sobald Sie dies haben, können Sie einfach danach sortieren. Die Dokumentation des Moduls enthält ein Beispiel, wie Sie zur Stammdomäne gelangen. –