演算法題:IP 地址和版本號排序

一杯綠茶發表於2021-11-09

在專案中遇到一個問題,需要對 IP 地址進行排序:

let arr = ["10.3.72.160", "10.3.71.106", "10.3.71.102", "10.3.69.108"]

思路很簡單,先實現一個比較兩個版本號的函式,然後作為陣列 sort 方法的 compareFunction 傳入。

function compare(a, b) {
  const a1 = a.split(".");
  const a2 = b.split(".");
  // IP 地址一共 4 位
  for (let n=0; n<4; n++) {
    const i = +a1[n];
    const j = +a2[n];
    if (i < j) return -1;
    else if (i > j) return 1;
  }
  return 0;
}
arr.sort(compare);

然後版本號排序有一點難度,因為版本號位數不固定。這裡假設版本號最多三位,即版本號可以取 1-3 位:

const versions = [
    '0.5.1',
    '0.1.1',
    '2.3.3',
    '0.302.1',
    '4.2',
    '4.3.5',
    '4.3.4'
];

還是一樣,先實現一個比較兩個版本號的函式,然後作為陣列 sort 方法的 compareFunction 傳入:

function compare(a, b) {
  const a1 = a.split(".");
  const a2 = b.split(".");
  // 版本號可以取 1-3 位
  // 位數不足就補零
  for (let n=0; n<3; n++) {
    const i = (n < a1.length) ? +a1[n] : 0;
    const j = (n < a2.length) ? +a2[n] : 0;
    if (i < j) return -1;
    else if (i > j) return 1;
  }
  return 0;
}
versions.sort(compare);

這裡介紹一個小技巧,陣列 sort 方法不傳 compareFunction 實際上也可以排序:

["10.3.72.160", "10.3.71.106", "10.3.71.102", "10.3.69.108"].sort();
// ['10.3.69.108', '10.3.71.102', '10.3.71.106', '10.3.72.160']

按照 MDN 文件的說法,如果沒有指明 compareFunction ,那麼元素會按照轉換為的字串的諸個字元的 Unicode 位點進行排序。

參考:

Array.prototype.sort() - MDN

相關文章