Сравните данные дерева в javascript

У меня есть две древовидные структуры: одна - исходное дерево, которое содержит все листья, другая - НАЗЫВАЕТСЯ selected, это просто копия исходного дерева и отсутствуют некоторые листья, мне нужно сравнить исходное дерево и selected и получить результат, такой же, как исходный, но просто обновить листы со сравнением с selected. Как и любой исходный лист содержит одних и тех же дочерних элементов, я хочу обновить исходный лист с помощью state: full. Если дочерние элементы не выбраны, состояние - state: no, если несколько дочерних элементов выбрано - state: partial.

Я пытался объединить выбранное дерево в массив идентификаторов, чтобы сопоставить выбранные с помощью source, но я застрял в логике обновления выходного дерева. пожалуйста, проверьте мой ожидаемый результат.

const recursCollectIds = ({tree}) => {
	return (tree || [])
  	.map(leaf => { return  (leaf.children && leaf.children.length) ? [leaf.id].concat(recursCollectIds({tree: leaf.children})) : [leaf.id] } )
    .flatMap(x => x)
}

const selected = [{
        id: 4,
        name: 'F',
        children: [{
            id: 8,
            name: 'V',
            children: []
        }, {
            id: 9,
            name: 'T',
            children: []
        }]
    },
    {
        id: 5,
        name: 'B',
        children: [{
            id: 17,
            name: 'R',
            children: []
        }]
    },
    {
        id: 7,
        name: 'O',
        children: [{
            id: 90,
            name: 'Y',
            children: [{
                id: 37,
                name: 'FU',
                children: []
            }]
        }]
    }
]

const source = [{
        id: 4,
        name: 'F',
        children: [{
            id: 8,
            name: 'V',
            children: [{
                id: 3,
                name: 'F',
                children: []
            }]
        }, {
            id: 9,
            name: 'T',
            children: []
        }]
    },
    {
        id: 5,
        name: 'B',
        children: [{
            id: 17,
            name: 'R',
            children: []
        }]
    },
    {
        id: 7,
        name: 'O',
        children: [{
            id: 90,
            name: 'Y',
            children: [{
                id: 37,
                name: 'FU',
                children: []
            }]
        }]
    }
]


const updateTree = ({source, selected}) => {
  const selectedIds = recursCollectIds({tree: selected})
  // need to check with ids of selected and source tree 
  
}

updateTree({source, selected})

Ожидаемый результат

    const out = [{
        state: 'partial', // due to its children or grand children is selected partially
        id: 4,
        name: 'F',
        children: [{
            state: 'partial', // due to its children or grand children is selected partially
            id: 8,
            name: 'V',
            children: [{
                state: 'no', // due to non of its children selected
                id: 3,
                name: 'F',
                children: []
            }]
        }, {
            state: 'full', // no children so no need to match. 
            id: 9,
            name: 'T',
            children: []
        }]
    },
    {
        state: 'full',
        id: 5,
        name: 'B',
        children: [{
            state: 'full',
            id: 17,
            name: 'R',
            children: []
        }]
    },
    {
        state: 'full',
        id: 7,
        name: 'O',
        children: [{
            state: 'full',
            id: 90,
            name: 'Y',
            children: [{
                state: 'full',
                id: 37,
                name: 'FU',
                children: []
            }]
        }]
    }
]
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
438
1

Ответы 1

const isUndefined = val => ((typeof val == "undefined") && (val == null));

const isArray = val => ((!isUndefined(val)) && (Array.isArray(val)));

const modifyObject = tree => {
    let respObject = {};
    (isArray(tree) ? tree : []).forEach(leaf => {
        respObject[leaf.id] = leaf;
        if (!isUndefined(leaf.children) && (leaf.children.length > 0)) {
            respObject[leaf.id]["children"] = modifyObject(leaf.children)
        }
    });
    return respObject;
}

const constructResp = (source,selected) => {
    return (isArray(source) ? source : []).map(currentElem=>{
        let currSourceChild = currentElem.children;
        currSourceChild = isUndefined(currSourceChild) ? [] : currSourceChild;
        let currElemSelectedChild = selected[currentElem.id];
        if (isUndefined(currElemSelectedChild)){
            currentElem['state'] = 'no';
            return currentElem;
        } else if (currSourceChild.length == 0){
            currentElem['state'] = 'full';
            return currentElem;
        } else{
            let currSourceUpdatedChild = constructResp(currSourceChild,currElemSelectedChild.children);
            let currIndex = 0;
            let childLen = currSourceUpdatedChild.length;
            for(;currIndex<childLen;currIndex++){
                if (currSourceUpdatedChild[currIndex].state != 'full'){
                    break;
                }
            }
            if (currIndex == childLen){
                currentElem['state'] = 'full';
            } else {
                currentElem['state'] = 'partial';
            }
            return currentElem;
        }
    })
}

const selected = [{
        id: 4,
        name: 'F',
        children: [{
            id: 8,
            name: 'V',
            children: []
        }, {
            id: 9,
            name: 'T',
            children: []
        }]
    },
    {
        id: 5,
        name: 'B',
        children: [{
            id: 17,
            name: 'R',
            children: []
        }]
    },
    {
        id: 7,
        name: 'O',
        children: [{
            id: 90,
            name: 'Y',
            children: [{
                id: 37,
                name: 'FU',
                children: []
            }]
        }]
    }
]

const source = [{
        id: 4,
        name: 'F',
        children: [{
            id: 8,
            name: 'V',
            children: [{
                id: 3,
                name: 'F',
                children: []
            }]
        }, {
            id: 9,
            name: 'T',
            children: []
        }]
    },
    {
        id: 5,
        name: 'B',
        children: [{
            id: 17,
            name: 'R',
            children: []
        }]
    },
    {
        id: 7,
        name: 'O',
        children: [{
            id: 90,
            name: 'Y',
            children: [{
                id: 37,
                name: 'FU',
                children: []
            }]
        }]
    }
]


const updateTree = ({source, selected}) => {
  let modifiedSelected = modifyObject(selected)
  let finalResp = constructResp(source,modifiedSelected);
  console.info(JSON.stringify(finalResp,null,4));
}

updateTree({source, selected})

Другие вопросы по теме