以编程方式查找特定节点并将 属性 添加到深层嵌套对象
Programmatically find specific node and add property to deep nested object
给定一个像这样的数组,其中最大深度可以是 3 个级别,而我们不知道研究项目可能在哪个级别:
const data = {
id: '1',
children: [
{
id: '2',
name: 'nameTest',
children: [
{
id: '3'
name: 'deepLevel'
}
]
}
}
如何在只知道值 'deepLevel' 的情况下将 属性 添加到第三层?
我们被允许使用 lodash 并强烈建议使用 ES6。
最终的数据结构应该是
给定一个像这样的数组,其中最大深度可以是 3 层:
const data = {
id: '1',
children: [
{
id: '2',
name: 'nameTest',
children: [
{
id: '3'
name: 'deepLevel'
addedProperty: true,
}
]
}
}
一种方法是通过自定义(可定制)条目(键值对)将查找嵌套项目的任务分开,并将额外的自定义数据分配给找到的项目。
因此,例如可以实现两种基于自递归的方法 recursivelyFindItemByEntry
和一个简单的 assignToObjectWithFirstMatchingNestedEntry
,它将提供的数据分配给前一个函数调用的结果 ...
function recursivelyFindItemByEntry(obj, [key, value]) {
let item;
if (!!obj && (typeof obj === 'object')) {
if (
obj.hasOwnProperty(key) &&
(obj[key] === value)
) {
item = obj;
} else if (
obj.hasOwnProperty('children') &&
Array.isArray(obj.children)
) {
obj.children.some(child => {
item = recursivelyFindItemByEntry(child, [key, value]);
return !!item;
});
}
}
return item;
}
function assignToObjectWithFirstMatchingNestedEntry(obj, [key, value], data) {
Object.assign(
recursivelyFindItemByEntry(obj, [key, value]) ?? {},
data ?? {}
);
return obj;
}
const data = {
id: '1',
children: [{
id: '2',
name: 'nameTest',
children: [{
id: '3',
name: 'deepLevel',
}, {
id: '4',
name: 'deepLevel',
}],
}, {
id: '5',
name: 'nameTest',
children: [{
id: '6',
name: 'deepLevel',
}, {
id: '7',
name: 'deepLevelTarget',
// addedProperty: true,
}, {
id: '8',
name: 'deepLevel',
}],
}, {
id: '9',
name: 'nameTest'
}, {
id: '10',
name: 'nameTestTarget'
}, {
id: '11',
name: 'nameTest'
}],
};
console.log(
"recursivelyFindItemByEntry(data, ['name', 'deepLevelTarget']) ...",
recursivelyFindItemByEntry(data, ['name', 'deepLevelTarget'])
);
console.log(
"recursivelyFindItemByEntry(data, ['id', '10']) ...",
recursivelyFindItemByEntry(data, ['id', '10'])
);
console.log('\n');
console.log(
"recursivelyFindItemByEntry(data, ['id', 'foo']) ...",
recursivelyFindItemByEntry(data, ['id', 'foo'])
);
console.log(
"recursivelyFindItemByEntry(data, ['id', '1']) ...",
recursivelyFindItemByEntry(data, ['id', '1'])
);
console.log('\n');
console.log(
"assignToObjectWithFirstMatchingNestedEntry(data, ['name', 'deepLevelTarget']), { addedProperty: true } ...",
assignToObjectWithFirstMatchingNestedEntry(data, ['name', 'deepLevelTarget'], { addedProperty: true })
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
给定一个像这样的数组,其中最大深度可以是 3 个级别,而我们不知道研究项目可能在哪个级别:
const data = {
id: '1',
children: [
{
id: '2',
name: 'nameTest',
children: [
{
id: '3'
name: 'deepLevel'
}
]
}
}
如何在只知道值 'deepLevel' 的情况下将 属性 添加到第三层? 我们被允许使用 lodash 并强烈建议使用 ES6。
最终的数据结构应该是
给定一个像这样的数组,其中最大深度可以是 3 层:
const data = {
id: '1',
children: [
{
id: '2',
name: 'nameTest',
children: [
{
id: '3'
name: 'deepLevel'
addedProperty: true,
}
]
}
}
一种方法是通过自定义(可定制)条目(键值对)将查找嵌套项目的任务分开,并将额外的自定义数据分配给找到的项目。
因此,例如可以实现两种基于自递归的方法 recursivelyFindItemByEntry
和一个简单的 assignToObjectWithFirstMatchingNestedEntry
,它将提供的数据分配给前一个函数调用的结果 ...
function recursivelyFindItemByEntry(obj, [key, value]) {
let item;
if (!!obj && (typeof obj === 'object')) {
if (
obj.hasOwnProperty(key) &&
(obj[key] === value)
) {
item = obj;
} else if (
obj.hasOwnProperty('children') &&
Array.isArray(obj.children)
) {
obj.children.some(child => {
item = recursivelyFindItemByEntry(child, [key, value]);
return !!item;
});
}
}
return item;
}
function assignToObjectWithFirstMatchingNestedEntry(obj, [key, value], data) {
Object.assign(
recursivelyFindItemByEntry(obj, [key, value]) ?? {},
data ?? {}
);
return obj;
}
const data = {
id: '1',
children: [{
id: '2',
name: 'nameTest',
children: [{
id: '3',
name: 'deepLevel',
}, {
id: '4',
name: 'deepLevel',
}],
}, {
id: '5',
name: 'nameTest',
children: [{
id: '6',
name: 'deepLevel',
}, {
id: '7',
name: 'deepLevelTarget',
// addedProperty: true,
}, {
id: '8',
name: 'deepLevel',
}],
}, {
id: '9',
name: 'nameTest'
}, {
id: '10',
name: 'nameTestTarget'
}, {
id: '11',
name: 'nameTest'
}],
};
console.log(
"recursivelyFindItemByEntry(data, ['name', 'deepLevelTarget']) ...",
recursivelyFindItemByEntry(data, ['name', 'deepLevelTarget'])
);
console.log(
"recursivelyFindItemByEntry(data, ['id', '10']) ...",
recursivelyFindItemByEntry(data, ['id', '10'])
);
console.log('\n');
console.log(
"recursivelyFindItemByEntry(data, ['id', 'foo']) ...",
recursivelyFindItemByEntry(data, ['id', 'foo'])
);
console.log(
"recursivelyFindItemByEntry(data, ['id', '1']) ...",
recursivelyFindItemByEntry(data, ['id', '1'])
);
console.log('\n');
console.log(
"assignToObjectWithFirstMatchingNestedEntry(data, ['name', 'deepLevelTarget']), { addedProperty: true } ...",
assignToObjectWithFirstMatchingNestedEntry(data, ['name', 'deepLevelTarget'], { addedProperty: true })
);
.as-console-wrapper { min-height: 100%!important; top: 0; }