我有一個型別的專案串列PartiePos......只需使用該方案:
{
ID: string
}
現在,我還有兩個型別的專案串列string。
這里所有三個串列:
items = [{ID: "123"}, {ID: "234"}, {ID: "345"}, {ID: "456"}, {ID: "567"}]
assigned = ["123", "345"]
disabled = ["567", "234"]
我想根據這個方案對它們進行排序:
- 始終保持物品的初始順序
- 如果已分配,請將其放在最后,但保持專案的初始順序
- 如果處于禁用狀態,則將其放在分配的末尾,但保持專案的初始順序
將我的串列決議為這個排序的輸出:
"456"
"123"
"345"
"234"
"567"
我通過將這兩個比較器應用于我的串列排序來實作這一點:
const comparatorA = (a: PartiePos, b: PartiePos) => {
if (assigned.includes(a.ID) && assigned.includes(b.ID)) {
return 0
}
if (assigned.includes(a.ID) && ! assigned.includes(b.ID)) {
return 1
}
if (! assigned.includes(a.ID) && assigned.includes(b.ID)) {
return -1
}
}
const comparatorD = (a: PartiePos, b: PartiePos) => {
if (disabled.includes(a.ID) && disabled.includes(b.ID)) {
return 0
}
if (disabled.includes(a.ID) && ! disabled.includes(b.ID)) {
return 1
}
if (! disabled.includes(a.ID) && disabled.includes(b.ID)) {
return -1
}
}
[...]
return items.sort(comparatorA).sort(comparatorD)
但是排序很慢并且阻塞了我的網站,開發控制臺告訴我我有一個遞回突變,這會導致阻塞 javascript。
知道如何改進嗎?
uj5u.com熱心網友回復:
沒有必要在這里排序,因為這需要O(n log n)時間。您可以過濾掉禁用和分配的專案,然后僅連接這些專案:
const items = [{ID: "123"}, {ID: "234"}, {ID: "345"}, {ID: "456"}, {ID: "567"}];
// If these are long, use a JS `new Set` object for fast lookup;
const assigned = ["123", "345"];
const disabled = ["567", "234"];
// just those that keep their regular place
const withoutAssignedAndDisabled = items.filter(x => !assigned.includes(x.ID) && !disabled.includes(x.ID));
// concat the assigned and then disabled
const result = withoutAssignedAndDisabled.concat(
items.filter(x => assigned.includes(x.ID))
).concat(
items.filter(x => disabled.includes(x.ID))
);
uj5u.com熱心網友回復:
我想出了一個有趣的方法,回來發布它,發現 Benjamin Gruenbaum 給出了一個更好的答案。
但這仍然很有趣,我認為可能對許多場景有用,所以我仍然會發布它:
const using = ((table) => (assigned, disabled) => (
{ID: x}, {ID: y},
kx = assigned .includes (x) ? 'a' : disabled .includes (x) ? 'd' : '_',
ky = assigned .includes (y) ? 'a' : disabled .includes (y) ? 'd' : '_',
) => table [kx] [ky])({
//x↓ y→
a: {a: 0, d: -1, _: 1},
d: {a: 1, d: 0, _: -1},
_: {a: -1, d: 1, _: 0}
})
const items = [{ID: "123"}, {ID: "234"}, {ID: "345"}, {ID: "456"}, {ID: "567"}]
const assigned = ["123", "345"]
const disabled = ["567", "234"]
console .log (items .sort (using (assigned, disabled)))
.as-console-wrapper {max-height: 100% !important; top: 0}
assigned在這里,我們對從和類別派生的簡單鍵使用表查找disabled(假設它們是互斥的)。
為了處理我們有兩個屬于同一類別的情況,我們利用了所有現代 JS 引擎都是穩定的并且只是 return 的事實0。
顯然,我們可以使用陣列陣列而不是類別字母來做到這一點,但我認為這更清楚,如果我們愿意,它會讓我們更明確,選擇使用“assigned”/“derived”/“neither”代替“a”/“d”/“_”。在任何情況下,結果矩陣都需要反對稱才能有意義。
很容易想象這個的概括,它接受一個函式,該函式生成一個鍵和一個解釋任何類別對的排序結果的表。但是由于本杰明已經給出了明確的答案,我將把它留到另一天。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/435314.html
標籤:javascript 打字稿 递归 比较器 阻塞
