[英]Convert array of objects with parent / child relationships to array of nested objects
[英]Reorder array of objects that contain parent/child relationships with lodash or vanilla js
我有一系列對象,例如:
[
{
id: 8,
name: 'Shirts',
slug: 'shirts',
parent_id: null
},
{
id: 9,
name: 'Pants',
slug: 'pants',
parent_id: null
},
{
id: 10,
name: 'Vintage Prints',
slug: 'vintage-prints',
parent_id: 8
},
{
id: 11,
name: 'Cotton Tee',
slug: 'cotton-tee',
parent_id: 8
},
{
id: 12,
name: 'Business Khakis',
slug: 'business-khakis',
parent_id: 9
}
]
我需要的是:
[
{
id: 9,
name: 'Pants',
slug: 'pants',
parent_id: null
},
{
id: 12,
name: 'Business Khakis',
slug: 'business-khakis',
parent_id: 9
},
{
id: 8,
name: 'Shirts',
slug: 'shirts',
parent_id: null
},
{
id: 11,
name: 'Cotton Tee',
slug: 'cotton-tee',
parent_id: 8
},
{
id: 10,
name: 'Vintage Prints',
slug: 'vintage-prints',
parent_id: 8
}
]
我試過什么:這看起來應該有效:
_.orderBy(categories, ['parent_id', 'name'], ['asc', 'asc']);
但我想知道 parent_id 中的空值是否在搞亂它。
編輯:內部和外部結果也應按字母順序排序。 因此,外層的褲子在襯衫之前,棉質 T 恤在兒童層的 Vintage Prints 之前。 請記住,這可以是無限深的層,其中 Cotton Tee 可能是父級等等。
如果每個排序的 object 都可以接收一個索引或級別,以便您知道它嵌套了多少級別,那就太好了。
單一排序不起作用,因為父子關系在對數據進行排序時未考慮。
該解決方案分為三個部分:
按字母表對數據進行排序,因為以下樹是按插入順序構建的。
構建具有給定關系的樹。
遍歷樹並返回排序后的平面數據。
var data = [{ id: 8, name: 'Shirts', slug: 'shirts', parent_id: null }, { id: 9, name: 'Pants', slug: 'pants', parent_id: null }, { id: 10, name: 'Vintage Prints', slug: 'vintage-prints', parent_id: 8 }, { id: 11, name: 'Cotton Tee', slug: 'cotton-tee', parent_id: 8 }, { id: 12, name: 'Business Khakis', slug: 'business-khakis', parent_id: 9 }].sort(function (a, b) { return a.name.localeCompare(b.name); }), tree = function (data, root) { var r = [], o = {}; data.forEach(function (a) { o[a.id] = { data: a, children: o[a.id] && o[a.id].children }; if (a.parent_id === root) { r.push(o[a.id]); } else { o[a.parent_id] = o[a.parent_id] || {}; o[a.parent_id].children = o[a.parent_id].children || []; o[a.parent_id].children.push(o[a.id]); } }); return r; }(data, null), sorted = tree.reduce(function traverse(r, a) { return r.concat(a.data, (a.children || []).reduce(traverse, [])); }, []) console.log(sorted); console.log(tree);
.as-console-wrapper { max-height: 100%;important: top; 0; }
var data = [{ id: 8, name: 'Shirts', slug: 'shirts', parent_id: null }, { id: 9, name: 'Pants', slug: 'pants', parent_id: null }, { id: 10, name: 'Vintage Prints', slug: 'vintage-prints', parent_id: 8 }, { id: 11, name: 'Cotton Tee', slug: 'cotton-tee', parent_id: 8 }, { id: 12, name: 'Business Khakis', slug: 'business-khakis', parent_id: 9 }].sort(function (a, b) { return a.name.localeCompare(b.name); }), tree = function (data, root) { var r = [], o = {}; data.forEach(function (a) { o[a.id] = { data: a, children: o[a.id] && o[a.id].children }; if (a.parent_id === root) { r.push(o[a.id]); } else { o[a.parent_id] = o[a.parent_id] || {}; o[a.parent_id].children = o[a.parent_id].children || []; o[a.parent_id].children.push(o[a.id]); } }); return r; }(data, null), sorted = tree.reduce(function traverse(level) { return function (r, a) { a.data.level = level return r.concat(a.data, (a.children || []).reduce(traverse(level + 1), [])); }; }(0), []); console.log(sorted);
.as-console-wrapper { max-height: 100%;important: top; 0; }
這是我的解決方案
它處理多個嵌套元素。
我得到了一個解決方案,我使用 lodash 來實現數組相等性,但你也可以在純 JS 中實現它
const sortByLevel = (
array: ({ id: string, parent_id: string, level: number })[],
i: number = 0,
): ({ id: string, parent_id: string, level: number })[] => {
const sortedArray = array
.map((c) => ({ ...c, level: array.findIndex((a) => a.id === c.parent_id) }))
.sort((a, b) => a.level - b.level);
if (
_.isEqual(
sortedArray.map((c) => c.id),
array.map((c) => c.id),
)
)
return sortedArray;
return sortByLevel(sortedArray, i + 1);
};
const sortByParent = (array: { id: string, parent_id: string }[]): { id: string, parent_id: string }[] => {
return sortByLevel(
array
.map((c) => ({ ...c, level: array.findIndex((a) => a.id === c.parent_id) }))
.sort((a, b) => a.level - b.level),
1,
).map((c) => {
const { level, ...card } = c;
return card;
});
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.