根据子条件筛选嵌套的对象数组



有一个类别树。它是一个对象数组(在本例中为1个ob以儿童财产为抵押。children属性是一个数组,包含或者不包含其他类别对象等等)。每个对象还具有一个属性";禁用";。它可以是真的也可以是假的。起点是一些最底层的孩子"被禁用";设置为true。在这种情况下,所有这些都设置为true。任务是查找家长ID如果其所有残疾儿童都设置为true,则该残疾儿童必须设置为true。在里面在这种特殊情况下,必须找到所有的父母id,因为所有最底层的孩子都是残疾人设置为true。我的函数只返回最低级别的父级。我做错了什么?

let parentIdsToDisable = [];
function findParentIdsToDisable(tree) {
tree.forEach((category) => {
if (category.children.length > 0) {
if (category.children.every((child) => child.disabled === true)) {
category.disabled = true;
parentIdsToDisable.push(category.id);
}
}
findParentIdsToDisable(category.children);
});
}
const categories = [
{
id: 69,
name: 'Прикраси',
key: 'prykrasy',
description: 'Прикраси',
disabled: false,
mpath: '69.',
children: [
{
id: 70,
name: 'Аксесуари',
key: 'aksesyary-dlya-prykras',
description: 'Аксесуари для прикрас',
disabled: true,
mpath: '69.70.',
children: []
},
{
id: 72,
name: 'Ювелірні вироби',
key: 'uvelirni-vyroby',
description: 'Ювелірні вироби',
disabled: false,
mpath: '69.72.',
children: [
{
id: 73,
name: 'Срібло',
key: 'vyroby-iz-sribla',
description: 'Ювелірні вироби із срібла',
disabled: true,
mpath: '69.72.73.',
children: []
}
]
},
{
id: 71,
name: 'Біжутерія',
key: 'bizhuteriya',
description: 'Біжутерія',
disabled: true,
mpath: '69.71.',
children: []
}
]
}
]

您需要首先进行递归调用,如果当前项本身被禁用,还需要保存其id

function findParentIdsToDisable(tree) {
tree.forEach((category) => {
findParentIdsToDisable(category.children);
if (category.disabled) {
parentIdsToDisable.push(category.id);
}
if (category.children.length > 0) {
if (category.children.every((child) => child.disabled === true)) {
category.disabled = true;
parentIdsToDisable.push(category.id);
}
}
});
}

这将为您的数据生成[ 70, 73, 72, 71, 69 ]

您需要递归并将逻辑应用于每个子级,然后检查每个子级是否被禁用以查看是否禁用父级。

const categories=[{id:69,name:"Прикраси",key:"prykrasy",description:"Прикраси",disabled:!1,mpath:"69.",children:[{id:70,name:"Аксесуари",key:"aksesyary-dlya-prykras",description:"Аксесуари для прикрас",disabled:!0,mpath:"69.70.",children:[]},{id:72,name:"Ювелірні вироби",key:"uvelirni-vyroby",description:"Ювелірні вироби",disabled:!1,mpath:"69.72.",children:[{id:73,name:"Срібло",key:"vyroby-iz-sribla",description:"Ювелірні вироби із срібла",disabled:!0,mpath:"69.72.73.",children:[]}]},{id:71,name:"Біжутерія",key:"bizhuteriya",description:"Біжутерія",disabled:!0,mpath:"69.71.",children:[]}]}];
const disableObjectIfChildrenDisabled = (parent) => {
for (const child of parent.children ?? []) {
disableObjectIfChildrenDisabled(child);
}
if (parent.children?.every(child => child.disabled)) {
parent.disabled = true;
}
};
for (const parent of categories) {
disableObjectIfChildrenDisabled(parent);
}
console.log(categories);

另一种方法是简单地复制已经应用了更改的数据。这可能满足您的需要,也可能不满足您的需求,但它似乎比收集需要更改的ID并在之后对其进行处理更简单。

这是这个想法的一个相当简单的递归实现:

const bubbleDisabled = (xs) =>
xs .map (({children, disabled, kids = bubbleDisabled (children), ...rest}) => ({
...rest,
disabled: disabled || (kids .length > 0 && kids .every (k => k .disabled)),
children: kids
}))
const categories = [{id: 69, name: "Прикраси", key: "prykrasy", description: "Прикраси", disabled: false, mpath: "69.", children: [{id: 70, name: "Аксесуари", key: "aksesyary-dlya-prykras", description: "Аксесуари для прикрас", disabled: true, mpath: "69.70.", children: []}, {id: 72, name: "Ювелірні вироби", key: "uvelirni-vyroby", description: "Ювелірні вироби", disabled: false, mpath: "69.72.", children: [{id: 73, name: "Срібло", key: "vyroby-iz-sribla", description: "Ювелірні вироби із срібла", disabled: true, mpath: "69.72.73.", children: []}]}, {id: 71, name: "Біжутерія", key: "bizhuteriya", description: "Біжутерія", disabled: true, mpath: "69.71.", children: []}]}]
console .log (bubbleDisabled (categories))
.as-console-wrapper {max-height: 100% !important; top: 0}

我们需要length检查,因为every将(正确地)为空数组返回true,我想我们不想将其冒泡到其父数组中。此外,我们使用disabled ||,因为我认为如果一个节点已经被禁用,我们不想基于子节点来启用它。如果任一假设都是错误的,则可以简化disabled的赋值。

最新更新