我正在尝试从现有的深层嵌套对象构建一个新对象。我似乎无法在递归模式下思考,但我遇到了一些麻烦:
oldObjArr = [{
id:1,
name:"Record1"
},{
id:2,
name:"Record2"
},{
id:3,
name:"Record3",
kids:[{
id: 4,
name: "Child 3-1"
},{
id: 5,
name: "Child 3-2"
}]
}]
buildTreeNodes = (node) => {
let data = []
node.map(record=>{
record["icon"] = "..."
record["color"] = "..."
data.push(record)
record.kids && buildTreeNodes(record.kids)
})
}
let newObjArr = buildTreeNodes(oldObjArr)
这显然不起作用,但我不知道什么会起作用。生成的对象应如下所示:
[{
id:1,
name:"Record1",
icon:"...",
color: "...",
},{
id:2,
name:"Record2",
icon:"...",
color: "...",
},{
id:3,
name:"Record3",
icon:"...",
color: "...",
kids:[{
id: 4,
name: "Child 3-1",
icon:"...",
color: "...",
},{
id: 5,
name: "Child 3-2",
icon:"...",
color: "...",
}]
}]
感谢您的帮助。
答案 0 :(得分:2)
罗伯特的回答是正确的。
如果碰巧你也不想改变原始对象,那么你可以这样做。
也使用 ES6 特性,为什么不使用。
const oldObjArr = [{
id: 1,
name: "Record1"
}, {
id: 2,
name: "Record2"
}, {
id: 3,
name: "Record3",
kids: [{
id: 4,
name: "Child 3-1"
}, {
id: 5,
name: "Child 3-2"
}]
}];
function transformObject(item) {
if (Array.isArray(item.kids))
return {
...item, icon: '...', color: '...',
kids: item.kids.map(transformObject)
};
else
return {...item, icon: '...', color: '...' };
}
const newArray = oldObjArr.map(transformObject);
console.log(newArray);
答案 1 :(得分:1)
因此,您遍历数组并获取每个对象,然后向其中添加道具。然后你检查孩子是否存在并检查是否是数组。我使用instanceof,但像@Heretic Monkey point 一样,它可以是Array.isArray。您还可以在函数前面设置类型保护,检查数组参数是否为数组,那么您不必检查 kids 是否为数组类型。
const oldObjArr = [{
id:1,
name:"Record1"
},{
id:2,
name:"Record2"
},{
id:3,
name:"Record3",
kids:[{
id: 4,
name: "Child 3-1"
},{
id: 5,
name: "Child 3-2"
}]
}]
const addKeys = arr => {
for(const obj of arr){
obj['icon'] = "test"
obj['color'] = "test"
if("kids" in obj && obj.kids instanceof Array){
addKeys(obj.kids);
}
}
}
addKeys(oldObjArr)
console.log(oldObjArr)
V2
const addKeys = arr => {
if(!Array.isArray(arr))
return;
for(const obj of arr){
if(typeof obj !== "object")
continue;
obj['icon'] = "test"
obj['color'] = "test"
if("kids" in obj){
addKeys(obj.kids);
}
}
}
答案 2 :(得分:0)
好的,看看这个:
buildTreeNodes = (node) => {
let data = node.map(record=>{
record["icon"] = "..."
record["color"] = "..."
if (record.kids) record.kids = buildTreeNodes(record.kids);
return record;
})
return data;
}
let newObjArr = buildTreeNodes(oldObjArr)
console.log(newObjArr)
我认为这就是您所追求的。您必须在每次迭代 record
时返回 map
,它会将其直接添加到 data
数组中。内部递归的工作原理相同。
答案 3 :(得分:0)
所有细节都在下面的演示中评论
let objArr = [{
id: 1,
name: "Record 1"
}, {
id: 2,
name: "Record 2"
}, {
id: 3,
name: "Record 3",
kids: [{
id: 4,
name: "Child 3-1"
}, {
id: 5,
name: "Child 3-2"
}]
},
/*
An object with a nested object not in an array
*/
{
id: 6,
name: 'Record 6',
kid: {
id: 7,
name: 'Child 6-1'
}
},
/*
An object that's filtered out because it doesn't have 'id' key/property
*/
{
no: 0,
name: null
},
/*
An object that's filtered out because it doesn't have 'id' key/property BUT has a nested object that has 'id'
*/
{
no: 99,
name: 'Member 99',
kid: {
id: 8,
name: 'Scion 99-1'
}
}
];
/*
Pass an object that has the key/value pairs that you want added to other objects
*/
const props = {
icon: '...',
color: '...'
};
/*
Pass...
a single object: {obj} of objArr[]
a single key/property: 'id'
an object that contains the key/value pairs to be added to each object that has key/property of id: {props}
*/
const addProp = (obj, prop, keyVal) => {
/*
Convert {props} object into a 2D array
props = {icon: '...', color: '...'}
~TO~
kvArr = [['icon', '...'], ['color', '...']]
*/
let kvArr = Object.entries(keyVal);
/*
for Each key/value pair of kvArr[][]
assign them to the (obj} if it has ['prop']
as one of it's key/properties
(in this demo it's 'id')
*/
kvArr.forEach(([key, val]) => {
if (obj[prop]) {
obj[key] = val;
}
});
/*
Convert {obj} into a 2D array
obj = {id: 3, name: "Record 3", kids: [{ id: 4, name: "Child 3-1"}, {id: 5, name: "Child 3-2"}]}
~TO~
subArr = [['id', 3], ['name', "Record 3"], ['kids', [{id: 4, name: "Child 3-1"}, {id: 5, name: "Child 3-2"}]]
*/
let subArr = Object.entries(obj);
/*
for Each value of subArr[][] (ie ['v'])
if it's an [Array] call addProp and pass
the {obj} of subArr[][]
*/
/*
if it's an {obj} do the same as above
*/
subArr.forEach(([k, v]) => {
if (Array.isArray(v)) {
v.forEach(subObj => {
addProp(subObj, prop, keyVal);
});
} else if (v instanceof Object) {
addProp(v, prop, keyVal);
}
});
};
// Run addProp() on each {obj} of objArr[]
for (let object of objArr) {
addProp(object, 'id', props);
}
console.log(JSON.stringify(objArr, null, 2));