通过检查其 属性 来更新父数组:Javascript
Update the parent array by checking its property: Javascript
我有一个深度嵌套的对象数组 arr1
具有某些属性,并给定另一个数组 arr2
作为输入,需要比较其中的相应名称并获取值并追加它到阵列之一。如果名称不在 arr2
中,则设置为默认配置,即 { val1: false, val2: false, applyToChildren: false }
,以防其父 applyToChildren
设置为 false
。如果它设置为 true,则将其父配置复制到结果中。
结构看起来像,
const arr1 = [
{
name: "internalcorp.com",
children: [
{
name: "internalcorp.com.child1",
children: [
{
name: "internalcorp.com.grandchild1",
children: []
}
]
},
{
name: "internalcorp.com.child2",
children: []
}
]
},
{
name: "internalcorpwebsite.com",
children: []
}
];
const arr2 = [
{
name: "internalcorp.com",
val1: false,
val2: false,
applyToChildren: true
},
{
name: "internalcorp.com.child1",
val1: true,
val2: true,
applyToChildren: true
},
{
name: "internalcorp.com.child2",
val1: true,
val2: false,
applyToChildren: true
},
{
name: "internalcorpwebsite.com",
val1: false,
val2: false,
applyToChildren: true
}
];
输出应该是这样的,
const output = [
{
name: "internalcorp.com",
config: {
val1: false,
val2: false,
applyToChildren: true
},
children: [
{
name: "internalcorp.com.child1",
config: {
val1: true,
val2: true,
applyToChildren: true
},
children: [
{
name: "internalcorp.com.grandchild1",
children: [],
config: {
val1: true,
val2: true,
applyToChildren: true
}
}
]
},
{
name: "internalcorp.com.child2",
children: [],
config: {
val1: true,
val2: false,
applyToChildren: true
}
}
]
},
{
name: "internalcorpwebsite.com",
children: [],
config: {
val1: false,
val2: false,
applyToChildren: true
}
}
];
此处 internalcorp.com.grandchild2
不存在于 arr2 中,因为它的父 applyToChildren
是 true
,我将其配置复制到结果
我试过的代码
const addConfig = (items) =>
items.map(item => {
const { val1, val2, applyToChildren } = arr2.find(p => p.name === item.name);
return {
...item,
config: {
val1,
val2,
applyToChildren
},
children: addConfig(item.children)
};
});
const result = addConfig(arr1);
你可以用一个简单的 Array.forEach
逻辑。
- 遍历
arr1
中的每个对象
- 检查
arr1
中的每个对象,如果 arr2
中存在具有相同 name
的值。
- 如果存在更新该节点的
config
。
- 如果没有,请检查其父项是否设置了
applyToChildren
。
- 如果设置使用父级的配置
- 否则使用默认配置
- 我已经使用
JSON.parse(JSON.stringify(arr1))
作为参数,以确保执行深拷贝
沃林Fiddle
const arr1 = [{name: "internalcorp.com", children: [{name: "internalcorp.com.child1",children: [ { name: "internalcorp.com.grandchild1", children: [] } ]},{name: "internalcorp.com.child2",children: []}]},{name: "internalcorpwebsite.com",children: []}];
const arr2 = [{ name: "internalcorp.com", val1: false, val2: false, applyToChildren: true },{ name: "internalcorp.com.child1", val1: true, val2: true, applyToChildren: true },{ name: "internalcorp.com.child2", val1: true, val2: false, applyToChildren: true },{ name: "internalcorpwebsite.com", val1: false, val2: false, applyToChildren: true }];
const defaultConfig = { val1: false, val2: false, applyToChildren: false };
const addConfig = (items, parentNode) => {
items.forEach((node) => {
const valueNode = arr2.find(value => value.name === node.name);
if(valueNode) {
const { name, ...config } = valueNode;
node.config = config;
} else {
if (parentNode && parentNode.config && parentNode.config.applyToChildren) {
node.config = parentNode.config;
} else {
node.config = defaultConfig;
}
}
if(node.children && node.children.length > 0) {
node.children.forEach(child => addConfig(node.children, node))
}
})
return items;
}
const result = addConfig(JSON.parse(JSON.stringify(arr1)), null);
console.log(result);
以下提供的解决方案使用递归 map
based approach. It in addition utilizes the so often forgotten thisArg
参数,可以作为 map
的第二个参数提供,其中 thisArg
然后作为回调的(映射函数的)this
上下文。
该解决方案还将子项目 config
数组转换为一个对象,该对象用于基于项目 name
的更简单的项目特定配置查找。为了将父级特定配置更深入地传递到递归中,绑定配置数据以 {lookup, config}
形式提供,其中 lookup
包含整个配置数据,而 config
包含最多的引用最近父项目的配置。
function recursivelyAggregateChildItemFromBoundConfigData(item) {
const { lookup, config: parentConfig } = this;
const { name, children = [] } = item;
const config = { ...(lookup[name] ?? parentConfig) };
// { ...{} } decouples any direct `config` reference.
return {
name,
config,
children: children.map(
recursivelyAggregateChildItemFromBoundConfigData,
{ lookup, config }
),
};
}
const nestedData = [{
name: "internalcorp.com",
children: [{
name: "internalcorp.com.child1",
children: [{
name: "internalcorp.com.grandchild1",
children: [],
}],
}, {
name: "internalcorp.com.child2",
children: [],
}],
}, {
name: "internalcorpwebsite.com",
children: []
}];
const itemConfigList = [{
name: "internalcorp.com",
val1: false,
val2: false,
applyToChildren: true
}, {
name: "internalcorp.com.child1",
val1: true,
val2: true,
applyToChildren: true
}, {
name: "internalcorp.com.child2",
val1: true,
val2: false,
applyToChildren: true
}, {
name: "internalcorpwebsite.com",
val1: false,
val2: false,
applyToChildren: true
}];
console.log(
'lookup table/index/map ...',
Object.fromEntries(
itemConfigList.map(({ name:key, ...value }) => [key, value])
)
);
console.log(
'recursively mapped nested data ...',
nestedData.map(recursivelyAggregateChildItemFromBoundConfigData, {
lookup: Object.fromEntries(
itemConfigList.map(({ name:key, ...value }) => [key, value])
),
config: null,
})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
我有一个深度嵌套的对象数组 arr1
具有某些属性,并给定另一个数组 arr2
作为输入,需要比较其中的相应名称并获取值并追加它到阵列之一。如果名称不在 arr2
中,则设置为默认配置,即 { val1: false, val2: false, applyToChildren: false }
,以防其父 applyToChildren
设置为 false
。如果它设置为 true,则将其父配置复制到结果中。
结构看起来像,
const arr1 = [
{
name: "internalcorp.com",
children: [
{
name: "internalcorp.com.child1",
children: [
{
name: "internalcorp.com.grandchild1",
children: []
}
]
},
{
name: "internalcorp.com.child2",
children: []
}
]
},
{
name: "internalcorpwebsite.com",
children: []
}
];
const arr2 = [
{
name: "internalcorp.com",
val1: false,
val2: false,
applyToChildren: true
},
{
name: "internalcorp.com.child1",
val1: true,
val2: true,
applyToChildren: true
},
{
name: "internalcorp.com.child2",
val1: true,
val2: false,
applyToChildren: true
},
{
name: "internalcorpwebsite.com",
val1: false,
val2: false,
applyToChildren: true
}
];
输出应该是这样的,
const output = [
{
name: "internalcorp.com",
config: {
val1: false,
val2: false,
applyToChildren: true
},
children: [
{
name: "internalcorp.com.child1",
config: {
val1: true,
val2: true,
applyToChildren: true
},
children: [
{
name: "internalcorp.com.grandchild1",
children: [],
config: {
val1: true,
val2: true,
applyToChildren: true
}
}
]
},
{
name: "internalcorp.com.child2",
children: [],
config: {
val1: true,
val2: false,
applyToChildren: true
}
}
]
},
{
name: "internalcorpwebsite.com",
children: [],
config: {
val1: false,
val2: false,
applyToChildren: true
}
}
];
此处 internalcorp.com.grandchild2
不存在于 arr2 中,因为它的父 applyToChildren
是 true
,我将其配置复制到结果
我试过的代码
const addConfig = (items) =>
items.map(item => {
const { val1, val2, applyToChildren } = arr2.find(p => p.name === item.name);
return {
...item,
config: {
val1,
val2,
applyToChildren
},
children: addConfig(item.children)
};
});
const result = addConfig(arr1);
你可以用一个简单的 Array.forEach
逻辑。
- 遍历
arr1
中的每个对象
- 检查
arr1
中的每个对象,如果arr2
中存在具有相同name
的值。 - 如果存在更新该节点的
config
。 - 如果没有,请检查其父项是否设置了
applyToChildren
。 - 如果设置使用父级的配置
- 否则使用默认配置
- 我已经使用
JSON.parse(JSON.stringify(arr1))
作为参数,以确保执行深拷贝
沃林Fiddle
const arr1 = [{name: "internalcorp.com", children: [{name: "internalcorp.com.child1",children: [ { name: "internalcorp.com.grandchild1", children: [] } ]},{name: "internalcorp.com.child2",children: []}]},{name: "internalcorpwebsite.com",children: []}];
const arr2 = [{ name: "internalcorp.com", val1: false, val2: false, applyToChildren: true },{ name: "internalcorp.com.child1", val1: true, val2: true, applyToChildren: true },{ name: "internalcorp.com.child2", val1: true, val2: false, applyToChildren: true },{ name: "internalcorpwebsite.com", val1: false, val2: false, applyToChildren: true }];
const defaultConfig = { val1: false, val2: false, applyToChildren: false };
const addConfig = (items, parentNode) => {
items.forEach((node) => {
const valueNode = arr2.find(value => value.name === node.name);
if(valueNode) {
const { name, ...config } = valueNode;
node.config = config;
} else {
if (parentNode && parentNode.config && parentNode.config.applyToChildren) {
node.config = parentNode.config;
} else {
node.config = defaultConfig;
}
}
if(node.children && node.children.length > 0) {
node.children.forEach(child => addConfig(node.children, node))
}
})
return items;
}
const result = addConfig(JSON.parse(JSON.stringify(arr1)), null);
console.log(result);
以下提供的解决方案使用递归 map
based approach. It in addition utilizes the so often forgotten thisArg
参数,可以作为 map
的第二个参数提供,其中 thisArg
然后作为回调的(映射函数的)this
上下文。
该解决方案还将子项目 config
数组转换为一个对象,该对象用于基于项目 name
的更简单的项目特定配置查找。为了将父级特定配置更深入地传递到递归中,绑定配置数据以 {lookup, config}
形式提供,其中 lookup
包含整个配置数据,而 config
包含最多的引用最近父项目的配置。
function recursivelyAggregateChildItemFromBoundConfigData(item) {
const { lookup, config: parentConfig } = this;
const { name, children = [] } = item;
const config = { ...(lookup[name] ?? parentConfig) };
// { ...{} } decouples any direct `config` reference.
return {
name,
config,
children: children.map(
recursivelyAggregateChildItemFromBoundConfigData,
{ lookup, config }
),
};
}
const nestedData = [{
name: "internalcorp.com",
children: [{
name: "internalcorp.com.child1",
children: [{
name: "internalcorp.com.grandchild1",
children: [],
}],
}, {
name: "internalcorp.com.child2",
children: [],
}],
}, {
name: "internalcorpwebsite.com",
children: []
}];
const itemConfigList = [{
name: "internalcorp.com",
val1: false,
val2: false,
applyToChildren: true
}, {
name: "internalcorp.com.child1",
val1: true,
val2: true,
applyToChildren: true
}, {
name: "internalcorp.com.child2",
val1: true,
val2: false,
applyToChildren: true
}, {
name: "internalcorpwebsite.com",
val1: false,
val2: false,
applyToChildren: true
}];
console.log(
'lookup table/index/map ...',
Object.fromEntries(
itemConfigList.map(({ name:key, ...value }) => [key, value])
)
);
console.log(
'recursively mapped nested data ...',
nestedData.map(recursivelyAggregateChildItemFromBoundConfigData, {
lookup: Object.fromEntries(
itemConfigList.map(({ name:key, ...value }) => [key, value])
),
config: null,
})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }