category: javascript

JavaScript - 處理一些排序的方式

on 2020-11-18

常常會遇到用 JavaScript 處理一些資料結構的排序

這裡會列舉一些使用情境與案例

取出排名前幾名的資料(排名的值不重複)

資料

var data = {
  123: {
    count: 123,
    type: "video",
    source: "",
  },
  345: {
    count: 345,
    type: "video",
    source: "",
  },
  99: {
    count: 99,
    type: "image",
    source: "",
  },
  1: {
    count: 1,
    type: "video",
    source: "",
  },
  9786: {
    count: 9786,
    type: "image",
    source: "",
  },
  347: {
    count: 347,
    type: "video",
    source: "",
  },
};

處理方式

function topNine(data) {
  var arr = [];
  (tmp = Object.keys(data).reverse()), (l = tmp.length >= 9 ? 9 : tmp.length);
  for (let i = 0; i < l; i++) {
    arr.push(data[tmp[i]]);
  }
  return arr;
}

處理範例為取出前 9 筆

這樣的處理是使用 Object 的 Key 的排序本身是升冪排序

為了讓代碼好讀懂

使用了 Object.keys(data).reverse() 反轉陣列使其變成降冪排序

這樣跑 for 迴圈就可以自然而然的從 0 開始

考慮到資料可能不到 9 筆

所以用 (tmp.length >= 9) ? 9 : tmp.length 來處理迴圈要跑的次數

這樣這個函數就可以回傳前 9 名的資料了

但是這樣的資料結構有個問題就是範例資料的 count 必須是唯一值, 因為 JSON Object 不能重複 key

取出排名前幾名的資料(排名的值重複)

資料

var data = [
  {
    source: "",
    type: "image",
    ts: 1600860409000,
    liked: 9680,
  },
  {
    source: "",
    type: "image",
    ts: 1603438465000,
    liked: 11746,
  },
  {
    source: "",
    type: "image",
    ts: 1602389743000,
    liked: 13289,
  },
  {
    source: "",
    type: "image",
    ts: 1605334079000,
    liked: 14095,
  },
  {
    source: "",
    type: "image",
    ts: 1602652312000,
    liked: 14138,
  },
  {
    source: "",
    type: "image",
    ts: 1603275324000,
    liked: 14310,
  },
  {
    source: "",
    type: "image",
    ts: 1603600329000,
    liked: 14448,
  },
  {
    source: "",
    type: "image",
    ts: 1603080713000,
    liked: 14625,
  },
  {
    source: "",
    type: "image",
    ts: 1604823132000,
    liked: 15351,
  },
  {
    source: "",
    type: "image",
    ts: 1604919156000,
    liked: 15373,
  },
  {
    source: "",
    type: "image",
    ts: 1601123545000,
    liked: 15442,
  },
  {
    source: "",
    type: "image",
    ts: 1601544281000,
    liked: 16659,
  },
  {
    source: "",
    type: "image",
    ts: 1605088396000,
    liked: 17137,
  },
  {
    source: "",
    type: "image",
    ts: 1602749094000,
    liked: 17483,
  },
  {
    source: "",
    type: "image",
    ts: 1600928882000,
    liked: 17928,
  },
  {
    source: "",
    type: "image",
    ts: 1602562980000,
    liked: 18217,
  },
  {
    source: "",
    type: "image",
    ts: 1603709259000,
    liked: 21845,
  },
  {
    source: "",
    type: "image",
    ts: 1602470351000,
    liked: 22292,
  },
  {
    source: "",
    type: "image",
    ts: 1603887487000,
    liked: 22559,
  },
  {
    source: "",
    type: "image",
    ts: 1602846057000,
    liked: 22824,
  },
  {
    source: "",
    type: "image",
    ts: 1601465442000,
    liked: 25226,
  },
  {
    source: "",
    type: "image",
    ts: 1604736681000,
    liked: 25580,
  },
  {
    source: "",
    type: "image",
    ts: 1601285690000,
    liked: 25796,
  },
  {
    source: "",
    type: "image",
    ts: 1601693594000,
    liked: 26078,
  },
];

處理方式

第一種解法

function topNine(data) {
  var arr = [];
  var i, j, temp;
  for (i = 0; i < data.length - 1; i++) {
    for (j = 0; j < data.length - 1 - i; j++) {
      if (data[j]["liked"] < data[j + 1]["liked"]) {
        temp = data[j];
        data[j] = data[j + 1];
        data[j + 1] = temp;
      }
    }
  }
  var l = data.length >= 9 ? 9 : data.length;
  for (var n = 0; n < l; n++) {
    arr.push(data[n]);
  }
  return arr;
}

這個也不太難理解

第一個迴圈依照 liked 跑了一個降冪的氣泡排序(一般情況都是跑升冪)

temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;

這邊使用 variable swap 的技巧來做前後兩個值的交換

c = a;
a = b;
b = c;

第二個迴圈就是取出前 9 筆的 liked

一樣是在 data.length >= 9 ? 9 : data.length 確認未滿 9 筆的話就有多少取多少

第二種解法

因為資料是 Array

所以可以使用 sort 來處理

function topNine(data) {
  var arr = [];
  data = data.sort(function (a, b) {
    return b.liked - a.liked;
  });
  var l = data.length >= 9 ? 9 : data.length;
  for (var n = 0; n < l; n++) {
    arr.push(data[n]);
  }
  return arr;
}

sort 可以帶入 function 處理回傳的比較的參數

所以可以回傳物件的值得比較結果

如果預設升冪排序就用 a - b

降冪排序就用 b - a

refer - Array.prototype.sort()

Read more

JavaScript - 半形 全形 轉換

on 2019-01-30

JavaScript - 半形 全形 轉換

因為一個奇怪的需求?

需要把使用者輸入的東西轉成可以方便驗證的格式(這應該後端做吧?)

反正因為以前也做過半形轉成全形(痛苦的回憶, 為啥政府的 opendata 各縣市格式不一致就算了, 竟然還有全形半形的問題…)

這邊就簡單的只針對最前面的基本拉丁字母字元符號集作轉換

因為大部分的需求應該這樣就可以應付了?

但是空白字元要特殊處理

那接下來只要知道需要轉換的字元範圍即可

全形從 U+FF01U+FF5E

半形從 U+0021U+007E

把 16 進制轉換回來就是

65281 到 65374

33 到 126

上述怎麼轉的?

就是這樣

parseInt('0xFF01', 16)

只要判斷輸入的字元這這些編碼區間就進行轉換

trans char

所以簡單做了一個 demo 頁面

程式檢視原始碼即可

Refer - Wiki

Refer - Unicode / UTF-8 字元編碼區間表 - 2013

Read more