Sorting interface names
Immer derselbe Ärger. Sortieren von Interface Namen in Webfrontends. Am Ende kriegt man sowas und soll die schön sortieren.
FastEthernet1
Port-channel5
TenGigabitEthernet1/1/1
Port-channel10
eth0.5
TenGigabitEthernet1/1/1.3
eth0.5:3
FastEthernet1.1
TenGigabitEthernet2/2/32
eth0
Port-channel5.4055
ae0.3
Was sich erstmal als nicht so schlimm darstellt aber dann doch
beliebig doof wird. Wenn man einfach die handelsüblichen String
Sortierroutinen in Perl, Javascript oder einer anderen Sprache nimmt wird
Lexikografisch sortiert. Das geht natürlich beliebig schief.
So werden dann die Port-channel
falschrum sortiert:
Port-channel10
Port-channel5
was natürlich Lexikographisch absolut richtig ist aber leider nicht was was man haben möchte.
Also muss man den String an "word" Boundaries zerlegen wobei hier sowohl der Übergang von Buchstabe auf Zahl wie Sonderzeichen und auch umgekehrt gilt.
Wir klassifizieren die Zeichen:
function chartype(ch) {
if (ch >= 'a' && ch <= 'z') {
return 1;
}
if (ch >= 'A' && ch <= 'Z') {
return 1;
}
if (ch >= '0' && ch <= '9') {
return 2;
}
switch(ch) {
case('-'):
case('/'):
case(':'):
case('.'):
return 3;
}
return 0;
}
Danach zerlegen wir den String in ein array:
if (chartype(ch) != chartype(last)) {
elements.push(str.substr(0, i));
str=str.slice(i,str.length);
}
Danach sind die interfaces schön zerlegt:
["TenGigabitEthernet", "2", "/", "1", "/", "31"]
Und können danach ganz einfach das Array rekursiv vergleichen als
function für array.sort()
. Hier wird wenn es numerische Elemente
sind numerisch verglichen andernfalls wird localeCompare
bemüht.
Sollten die elemente gleich sein wird die nächste Ebene bemüht.
function shortlist_sort_deeparray(a, b, i) {
/* Elements numeric ? */
if (!isNaN(a[i]) && !isNaN(b[i])) {
rc=a[i]-b[i];
} else {
rc=a[i].localeCompare(b[i]);
}
if (rc == 0) {
return shortlist_sort_deeparray(a, b, i+1);
}
return rc;
}
Es gibt noch ein bischen Optimierungspotential. So könnte man den chartype 3
also die "Sonderzeichen" einfach nicht in das Array packen. Was natürlich
dann bei eth0:3
und eth0.3
zu undefiniertem Verhalten führt. Da es normalerweise
um <100 Interfaces geht macht das ganze auch wenig Sinn.
[[!img Error: "media/201601131032.sorting_interface_names.jpg" does not seem to be a valid jpeg file]]