我有一個 SharePoint 串列,我通過 REST 在 javascript 中進行操作。我需要將陣列從 REST 轉換為嵌套物件。我正在基于結構構建導航選單。該陣列由 ID、Title、Parent 和 Level 組成。級別是 Top、Mid 或 Bot,Parent 列出作為其父項的條目的 Title。
let orgs = [{
id: "0",
title: "A",
parent: "",
level: "Top"
},{
id: "1",
title: "Org A1",
parent: "A",
level: "Middle"
},
{
id: "2",
title: "Org A2",
parent: "A",
level: "Middle"
},
{
id: "3",
title: "Org A3",
parent: "A",
level: "Middle"
},
{
id: "5",
title: "Org A1-A",
parent: "Org A1",
level: "Bottom"
},
{
id: "6",
title: "Org A1-B",
parent: "Org A1",
level: "Bottom"
},
{
id: "7",
title: "Org A2-A",
parent: "Org A2",
level: "Bottom"
},
{
id: "8",
title: "Org A2-B",
parent: "Org A2",
level: "Bottom"
},
{
id: "9",
title: "Org A3-A",
parent: "Org A3",
level: "Bottom"
},
{
id: "10",
title: "Org A3-B",
parent: "Org A3",
level: "Bottom"
}
];
我正在嘗試遍歷陣列并將子項的標題添加到適當的父項。物件的目標結構是:
const orgObj = {
Title: "Org A",
mid: [{
Title: "Org A1",
bot: [{
Title: "Org A1-A"
}, {
Title: "Org A1-B"
}]
}, {
Title: "Org A2",
bot: [{
Title: "Org A2-A"
}, {
Title: "Org A2-B"
}]
}, {
Title: "Org A3",
bot: [{
Title: "Org A3-A"
}, {
Title: "Org A3-B"
}]
}]
};
我試圖使用地圖功能,但我無法讓結果正常作業。我一直在這幾天斷斷續續,似乎無法讓它作業。到目前為止,我無法訪問我在當前位置嘗試過的代碼,但我會在可以獲得它時嘗試更新。在我看來,這不應該是復雜的。
uj5u.com熱心網友回復:
這是一種方法...
let orgs = [{
id: "0",
title: "Org A",
parent: "",
level: "Top"
},{
id: "1",
title: "Org A1",
parent: "Org A",
level: "Middle"
},
{
id: "2",
title: "Org A2",
parent: "Org A",
level: "Middle"
},
{
id: "3",
title: "Org A3",
parent: "Org A",
level: "Middle"
},
{
id: "5",
title: "Org A1-A",
parent: "Org A1",
level: "Bottom"
},
{
id: "6",
title: "Org A1-B",
parent: "Org A1",
level: "Bottom"
},
{
id: "7",
title: "Org A2-A",
parent: "Org A2",
level: "Bottom"
},
{
id: "8",
title: "Org A2-B",
parent: "Org A2",
level: "Bottom"
},
{
id: "9",
title: "Org A3-A",
parent: "Org A3",
level: "Bottom"
},
{
id: "10",
title: "Org A3-B",
parent: "Org A3",
level: "Bottom"
}
];
let roots = {};
orgs.forEach(org => {
if (org.parent) {
let parent = orgs.find(o => o.title === org.parent)
if (parent.level === 'Top') {
if (!parent.mid) parent.mid = [];
parent.mid.push(org);
} else if (parent.level === 'Middle') {
if (!parent.bot) parent.bot = [];
parent.bot.push(org);
}
} else {
roots[org.title] = org;
}
})
console.log(JSON.stringify(Object.values(roots), null, 2));
uj5u.com熱心網友回復:
您可以使用以下演算法在線性時間內為您構建樹O(n)。
我在Maps這里大量使用以保持運行時線性。
首先,我創建一個Map將每個映射title到相應的資料。我稍后需要這個,以便我可以快速查找組織可能擁有的任何父級的資料。結果將是這樣的:
Map(10) {
'A' => { id: '0', title: 'A', parent: '', level: 'Top' },
'Org A1' => { id: '1', title: 'Org A1', parent: 'A', level: 'Middle' },
'Org A2' => { id: '2', title: 'Org A2', parent: 'A', level: 'Middle' },
'Org A3' => { id: '3', title: 'Org A3', parent: 'A', level: 'Middle' },
'Org A1-A' => { id: '5', title: 'Org A1-A', parent: 'Org A1', level: 'Bottom' },
'Org A1-B' => { id: '6', title: 'Org A1-B', parent: 'Org A1', level: 'Bottom' },
'Org A2-A' => { id: '7', title: 'Org A2-A', parent: 'Org A2', level: 'Bottom' },
'Org A2-B' => { id: '8', title: 'Org A2-B', parent: 'Org A2', level: 'Bottom' },
'Org A3-A' => { id: '9', title: 'Org A3-A', parent: 'Org A3', level: 'Bottom' },
'Org A3-B' => { id: '10', title: 'Org A3-B', parent: 'Org A3', level: 'Bottom' }
}
然后,我還在級別和道具名稱之間創建了一個映射,以說明您沒有統一的children道具,而是mid取決于bot父級的級別。
現在開始實際的樹構建。reduce()我再次使用一個空的 JavaScript 物件回圈遍歷所有組織。對于每個專案,我創建目標物件 ( newObj),它只包含Title并使用上面的獲取父物件Map。如果沒有父元素,這是最頂層的元素。
如果它不是父物件,我可以orgChart使用我的quickRefs Map. 然后我參考了樹中的父節點。現在我需要獲取children屬性的名稱mid或bot基于父級的級別。
現在使用該屬性名稱,我可以為父節點分配這個新屬性,其值為新的子物件。如果父物件已經有一個子物件,我可以簡單地將另一個子物件推送到該陣列上,如果沒有,我需要創建一個新陣列并將子物件推送到該陣列上。
最后但并非最不重要的一點是,我需要將對新物件的參考插入到 myquickRefs Map中,因此如果我以后遇到一個物件是現在插入的專案的子物件,我可以如上所述直接將子物件分配給該物件。
const input = [
{
id: "0",
title: "A",
parent: "",
level: "Top",
},
{
id: "1",
title: "Org A1",
parent: "A",
level: "Middle",
},
{
id: "2",
title: "Org A2",
parent: "A",
level: "Middle",
},
{
id: "3",
title: "Org A3",
parent: "A",
level: "Middle",
},
{
id: "5",
title: "Org A1-A",
parent: "Org A1",
level: "Bottom",
},
{
id: "6",
title: "Org A1-B",
parent: "Org A1",
level: "Bottom",
},
{
id: "7",
title: "Org A2-A",
parent: "Org A2",
level: "Bottom",
},
{
id: "8",
title: "Org A2-B",
parent: "Org A2",
level: "Bottom",
},
{
id: "9",
title: "Org A3-A",
parent: "Org A3",
level: "Bottom",
},
{
id: "10",
title: "Org A3-B",
parent: "Org A3",
level: "Bottom",
},
];
// store titles to their data so we can find a parent object in constant time
const map = input.reduce((all, cur) => (all.set(cur.title, cur), all), new Map());
// mapping for the property names
// if the parent is level "Top", we need to use "mid"
// if the parent is level "Middle", we need to use "bot"
const mapLevelToPropName = {
Top: "mid",
Middle: "bot",
}
// stores references to objects within the object, so they can be accessed in constant time
const quickRefs = new Map();
const output = input.reduce((orgChart, org) => {
const parent = map.get(org.parent);
const newObj = {
Title: org.title
}
if(parent === undefined) {
// top most org
orgChart = newObj
}
else {
// some org in the middle which has a parent
// get the reference to the parent within the JS object using the quickRefs map
const refToParentObj = quickRefs.get(org.parent)
// determine the name of the "children" property based on the level of the parent
const propName = mapLevelToPropName[parent.level];
// check if there already are childrens (mid, bot)
// if yes: append another one to array
if(refToParentObj[propName]) refToParentObj[propName].push(newObj);
// if no: add new object within an array
else refToParentObj[propName] = [newObj];
}
// add a reference to the new object into the quickRefs map so
// when we find a child we can just grab that reference and add the child
quickRefs.set(org.title, newObj);
return orgChart;
}, {})
console.log(JSON.stringify(output, null, 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
此實作假定子組織只出現在輸入陣列中的父組織之后,但適用于深度嵌套的結構(盡管“mid”、“bot”功能可能不適合此)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/480988.html
標籤:javascript 数组 目的
上一篇:如何回傳名字和姓氏的物件
