级联选择(元素指定值集合

若子元素全选取子元素与父元素值集合
若子元素未全选,则只取子元素值集合

/**
 * 处理级联选择结果
 * @param {Array[]} selectedPaths 选中的路径数组,如 [["66","603","1399","1791"], ["66","603","1399","1792"]]
 * @param {Object[]} fullTreeData 完整的树形结构数据
 * @param {string} field 节点ID字段,默认为 'id'
 * @returns {string[]} 处理后的集合数组
 */
export const processCascaderSelection = (selectedPaths, fullTreeData, field = 'id') => {
    // 1. 将选中的路径转换为扁平化的ID集合
    const selectedIds = new Set(selectedPaths.flat());

    // 2. 构建节点映射表和父子关系
    const nodeMap = new Map();
    const allChildrenMap = new Map(); // 存储每个节点的所有子节点ID

    const buildMaps = (nodes) => {
        nodes.forEach((node) => {
            nodeMap.set(node[field], node);

            if (node.children && node.children.length > 0) {
                const childrenIds = node.children.map((child) => child[field]);
                allChildrenMap.set(node[field], new Set(childrenIds));
                buildMaps(node.children);
            }
        });
    };

    buildMaps(fullTreeData);

    // 3. 处理结果集
    const result = new Set();

    // 4. 递归检查节点
    const checkNode = (nodeId) => {
        const node = nodeMap.get(nodeId);
        if (!node) return false;

        // 如果是叶子节点
        if (!node.children || node.children.length === 0) {
            if (selectedIds.has(nodeId)) {
                result.add(nodeId);
                return true;
            }
            return false;
        }

        // 获取所有子节点ID
        const allChildren = allChildrenMap.get(nodeId) || new Set();
        let allChildrenSelected = true;

        // 检查每个子节点是否被选中
        for (const childId of allChildren) {
            const childSelected = checkNode(childId);
            allChildrenSelected = allChildrenSelected && childSelected;
        }

        // 只有当所有子节点都被选中时,才添加当前节点
        if (allChildrenSelected && allChildren.size > 0) {
            result.add(nodeId);
            return true;
        }

        return false;
    };

    // 5. 从所有选中的顶级节点开始检查
    const topLevelSelected = new Set();
    selectedPaths.forEach((path) => {
        if (path.length > 0) {
            topLevelSelected.add(path[0]);
        }
    });

    topLevelSelected.forEach((nodeId) => {
        checkNode(nodeId);
    });

    return Array.from(result);
};
// 测试1: 全选一个分支
const test1 = processCascaderSelection([
  ["66","603","1399","1791"],
  ["66","603","1399","1792"],
  ["66","603","1399","4373"] // 选中1399的所有子节点
], fullTreeData);
console.log(test1); // 输出: ["1399"]
// 测试2: 部分选择
const test2 = processCascaderSelection([
  ["66","603","1399","1791"], // 只选中1399的一个子节点
  ["66","603","1793"]
], fullTreeData);
console.log(test2); // 输出: ["1791", "1793"]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。