hay un árbol de categorías. es una matriz de objetos (en este caso, 1 objeto con propiedad de niños. La propiedad de niños es una matriz que contiene o no contiene otras categorías de objetos, etc.). Cada objeto también tiene una propiedad "deshabilitada". Puede ser verdadero o falso. El punto de partida es que algunos niños inferiores "deshabilitados" se establecen en verdadero. En este caso, todos ellos se establecen en verdadero. La tarea es encontrar los ID de padres que deshabilitados deben configurarse como verdaderos si todos sus hijos deshabilitados están configurados como verdaderos. En este caso particular, se deben encontrar todos los ID de los padres porque todos los hijos deshabilitados en la parte inferior se establecen en verdadero. Mi función devuelve solo el nivel más bajo de los padres. ¿Qué estoy haciendo mal?
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: [] } ] } ]
Primero debe realizar la llamada recursiva y también guardar la id
del elemento actual si está deshabilitado.
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); } } }); }
Esto da como resultado [ 70, 73, 72, 71, 69 ]
para sus datos.
Debe repetir y aplicar la lógica a cada hijo antes de verificar si cada hijo está deshabilitado para ver si deshabilitar al padre o no.
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);
Otro enfoque sería simplemente hacer una copia de los datos con los cambios ya aplicados. Esto puede o no satisfacer sus necesidades, pero parece más simple que recopilar las identificaciones que deben cambiarse y hacer algo con ellas después.
Esta es una implementación recursiva bastante simple de esa idea:
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}
Necesitamos la verificación de length
porque every
(correctamente) devolverán true
para una matriz vacía, y asumo que no querríamos subir eso a sus padres. También usamos disabled ||
porque supongo que si un nodo ya está deshabilitado, no querríamos habilitarlo en función de los niños. Si cualquiera de las suposiciones es incorrecta, puede simplificar la asignación de disabled
.