[英]How to sort an array of complex objects?
我有這種對對象數組進行排序的方法,但是當我有一個復雜的結構時,例如:
const data = [ { title: 'Book title', author: 'John', info: { language: english, pages: 500, price: '$50' }} ]
我無法排序 object 'info: {language: english, pages: 500, price:'$50'}'
我的代碼:
import { useMemo, useState } from 'react';
interface SortConfigProps {
key: string;
direction: string;
}
export const useSortableData = <T>(items: T[]) => {
const [sortConfig, setSortConfig] = useState<SortConfigProps>(
{} as SortConfigProps,
);
const sortedItems = useMemo(() => {
const sortableItems = [...items];
if (sortConfig) {
sortableItems.sort((a: any, b: any) => {
if (a[sortConfig.key] < b[sortConfig.key]) {
return sortConfig.direction === 'ascending' ? -1 : 1;
}
if (a[sortConfig.key] > b[sortConfig.key]) {
return sortConfig.direction === 'ascending' ? 1 : -1;
}
return 0;
});
}
return sortableItems;
}, [items, sortConfig]);
const requestSort = (key: string) => {
let direction = 'ascending';
if (
sortConfig &&
sortConfig.key === key &&
sortConfig.direction === 'ascending'
) {
direction = 'descending';
}
setSortConfig({ key, direction });
};
return { items: sortedItems, requestSort, sortConfig };
};
您遇到的問題是 object 的深度克隆。擴展運算符僅深入 1 級,而您正在嘗試 go 兩級。 您可以使用來自 lodash 或其他深度克隆的庫。 我使用 JSON 技巧。
const [data, setData] = useState(initData);
function newArray() {
return JSON.parse(JSON.stringify(data));
}
示例顯示了兩個級別的排序: https://codesandbox.io/s/serverless-sea-jt220?file=/src/App.js
根據您的整體系統,有多種方法可以實現這一點,因此根據我的建議,我將假設以下內容:
'info.price'
中的點,或'info->price'
中的箭頭)。 定界符的一個重要屬性是在平面鍵中使用它是無效的(即在最后一個示例中不允許像data = [{ 'info->price': '$50' }]
這樣的東西)好的,現在你只需要實現一個訪問器來使用你的 object 上的復雜鍵,類似於Lodash.get 。 一個簡單的實現是這樣的:
const DELIMITER = '->';
function get(obj, key) {
if (!obj) {
// in case of null or undefined
return obj;
}
if (!key) {
// empty string or something like that
return obj;
}
if (key.includes(DELIMITER)) {
const keyComponents = key.split(DELIMITER);
const firstKeyComponent = keyComponents.shift();
const newKey = keyComponents.join(DELIMITER);
return get(obj[firstKeyComponent], newKey)
}
return obj[key];
}
這里強調簡單,因為每次都重新計算keyComponents
並不理想。 您可能還想為如何處理字符串或 arrays 添加額外的 if 情況,如果關鍵組件是數字,這些情況可能會導致問題。
編輯:也可以使用Object.prototype.hasOwnProperty
檢查密鑰是否與內置的 Object function 相同,或者更好地檢查 obj 是否為 function 並決定如何處理該場景。
在你有了這個之后,你可以用這個替換你的代碼的比較部分:
sortableItems.sort((a: any, b: any) => {
const aValue = get(a, sortConfig.key);
const bValue = get(b, sortConfig.key);
if (aValue < bValue) {
return sortConfig.direction === 'ascending' ? -1 : 1;
}
if (aValue] > bValue) {
return sortConfig.direction === 'ascending' ? 1 : -1;
}
return 0;
});
在大多數情況下,您可以撥打 go。 我不知道你的數據有多“狂野”,所以一定要測試一堆場景。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.