stable-sort-domain.ts 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import * as tldts from 'tldts';
  2. import { sort } from './timsort';
  3. export const compare = (a: string, b: string) => {
  4. if (a === b) return 0;
  5. const aLen = a.length;
  6. const r = aLen - b.length;
  7. if (r !== 0) return r;
  8. return a.localeCompare(b);
  9. };
  10. const tldtsOpt = { allowPrivateDomains: false, detectIp: false, validateHostname: false };
  11. export const sortDomains = (inputs: string[]) => {
  12. const domainMap = new Map<string, string>();
  13. const subdomainMap = new Map<string, string>();
  14. for (let i = 0, len = inputs.length; i < len; i++) {
  15. const cur = inputs[i];
  16. if (!domainMap.has(cur)) {
  17. const topD = tldts.getDomain(cur, tldtsOpt);
  18. domainMap.set(cur, topD ?? cur);
  19. }
  20. if (!subdomainMap.has(cur)) {
  21. const subD = tldts.getSubdomain(cur, tldtsOpt);
  22. subdomainMap.set(cur, subD ?? cur);
  23. }
  24. }
  25. const sorter = (a: string, b: string) => {
  26. if (a === b) return 0;
  27. const main_domain_a = domainMap.get(a)!;
  28. const main_domain_b = domainMap.get(b)!;
  29. let t = compare(main_domain_a, main_domain_b);
  30. if (t === 0) {
  31. const subdomain_a = subdomainMap.get(a)!;
  32. const subdomain_b = subdomainMap.get(b)!;
  33. t = compare(subdomain_a, subdomain_b);
  34. }
  35. if (t === 0 && (a !== main_domain_a || b !== main_domain_b)) {
  36. t = compare(a, b);
  37. }
  38. return t;
  39. };
  40. return sort(inputs, sorter);
  41. };