我一直在思考在我的應用程式中處理分組的最佳方式。這是一個視頻編輯應用程式,我正在介紹對圖層進行分組的功能。如果您熟悉 Figma 或任何設計/視頻編輯程式,那么通常可以對圖層進行分組。
為了在應用程式中保持簡單,視頻資料是一張地圖
const map = {
"123": {
uid: "123",
top: 25,
type: "text"
},
"345": {
uid: "345",
top: 5,
type: "image"
},
"567": {
uid: "567",
top: 25,
type: "group"
children: ["345", "123"]
}
}
然后我將它們分組到一個渲染函式中(這感覺很昂貴)
const SomeComponent = () => {
const objects = useMemo(() => makeTrackObjects(map), [map]);
return (
<div>
{objects.map(object => {
return <div>Some layer that will change the data causing re-renders</div>
})}
</div>
)
}
這是進行分組的功能
const makeTrackObjects = (map) => {
// converts map to array
const objects = Object.keys(map).map((key: string) => ({ ...map[key] }));
// flat array of all objects to be grouped by their key/id
const objectsInGroup = objects
.filter((object) => object.type === "group")
.map((object) => object.children)
.flat();
// filter out objects that are nested/grouped
const filtered = objects.filter((object) => !objectsInGroup.includes(object.uid))
// insert objects as children during render
const grouped = filtered.map((object) => {
const children = object.children
? {
children: object.children
.map((o, i) => {
return {
...map[o]
};
})
.flat()
}
: {};
return {
...object,
...children
};
});
// the core data is flat but now nested for the UI. Is this inefficient?
return grouped
}
理想情況下,我想保持資料平坦,我有很多代碼需要更新才能深入資料。在某些需要的地方讓它變平和變壓器感覺很好。
主要問題是這是否有意義,是否有效,如果沒有,為什么?
uj5u.com熱心網友回復:
如果您運行的性能問題,您可能需要調查的一個領域是你如何鏈接陣列功能(map,filter,flat等)。對這些函式之一的每次呼叫都會根據它接收到的陣列創建一個中間集合。(例如,如果我們鏈接了 2 個map函式,這將回圈整個陣列兩次)。您可以通過創建一個回圈并將專案添加到集合中來提高性能。(這里有一篇文章談到這是對換能器的動機。)
我以前沒有遇到過性能問題,但您可能還想...在不必要的時候洗掉 spread ( )。
這是我對這些調整的看法makeTrackObjects。
更新
我還注意到您在遍歷陣列時使用了包含。這實際上是O(n^2)時間復雜度,因為每個專案都將針對整個陣列進行掃描。一種緩解方法是改為使用 aSet檢查該內容是否已經存在,將其轉化為O(n)時間復雜度。
const map = {
"123": {
uid: "123",
top: 25,
type: "text"
},
"345": {
uid: "345",
top: 5,
type: "image"
},
"567": {
uid: "567",
top: 25,
type: "group",
children: ["345", "123"]
}
};
const makeTrackObjects = (map) => {
// converts map to array
const objects = Object.keys(map).map((key) => map[key]);
// set of all objects to be grouped by their key/id
const objectsInGroup = new Set();
objects.forEach(object => {
if (object.type === "group") {
object.children.forEach(child => objectsInGroup.add(child));
}
});
// filter out objects that are nested/grouped
const filtered = objects.filter((object) => !objectsInGroup.has(object.uid))
// insert objects as children during render
const grouped = filtered.map((object) => {
const children = {};
if (object.children) {
children.children = object.children.map(child => map[child]);
}
return {
...object,
...children
};
});
// the core data is flat but now nested for the UI. Is this inefficient?
return grouped
}
console.log(makeTrackObjects(map));
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/404905.html
標籤:
