JavaScript:使用lodash在相同的嵌套键之间进行过滤

时间:2019-07-03 08:05:56

标签: javascript lodash

我有一个数组baseTable,看起来像这样:

baseTable = [
    {
        exid: "2",
        name: "aa",
        children_meta: {
        has: false
        }
    },
    {
        exid: "1",
        name: "aa1",
        children_meta: {
        has: false
        }
    },
    {
        exid: "3",
        name: "bb",
        children_meta: {
        has: true
        },
        children: [
        {
            exid: "101",
            name: "c101"
        },
        {
            exid: "102",
            name: "c102"
        }
        ]
    }
]

和另一个数组againstTable像这样:

againstTable = [
    {
        exid: "2",
        name: "aa",
        children_meta: {
        has: false
        }
    },
    {
        exid: "3",
        name: "bb",
        children_meta: {
        has: true
        },
        children: [
        {
            exid: "102",
            name: "c102"
        }
        ]
    }
]

是否有lodash方法从baseTable数组中选择exid中不存在相同againstTable的对象?

为了说明,我需要一种可以从上面的两个数组中产生以下数组结果的方法:

 [
    {
    exid: "1",
    name: "aa1",
    children_meta: {
        has: false
    }
    },
    {
        exid: "3",
        name: "bb",
        children_meta: {
        has: true
        },
        children: [
            {
                exid: "101",
                name: "c101"
            }
        ]
    }
]

这就是我的尝试,但是对于一个小任务来说,这种方法变得太大了:

conditionalRender(o: { baseTable; againstTable }) {
    const { baseTable, againstTable } = o;
    // Check if there are no duplicates in the base
    // table; check against, "against table"
    // This could be possible after user performs a search
    console.log(baseTable, "..base");
    console.log(againstTable, "...againsr");
    const baseMap = {};
    const againstMap = {};
    baseTable.forEach(row => (baseMap[row.pid] = row));
    againstTable.forEach(row => (againstMap[row.pid] = row));

    // const against_ids = new Set(againstTable.map(({ pid }) => pid));
    // return baseTable.filter(({ pid }) => !against_ids.has(pid));
    const filteredBaseTable: { [index: string]: any } = [];
    baseTable.forEach(({ pid }) => {
    if (baseMap[pid].children_meta.has) {
        // If it is a group, check if there exists
        // a part in another table
        if (againstMap[pid]) {
        // Opposite table also has the same eequipment group
        // Will keep the children that are not present in the
        // opposite table
        // Each child can be differentiated by its exid
        const exidsInAgainstTable = new Set(
            againstMap[pid].children.map(crow => crow.exid)
        );
        // Keep only those ids in base table that do not exist in against table
        const originalBaseChildren = baseMap[pid].children;
        baseMap[pid].children = originalBaseChildren.filter(
            ({ exid }) => !exidsInAgainstTable.has(exid)
        );
        filteredBaseTable.push(baseMap[pid]);
        }
    } else {
        if (!againstMap[pid]) {
        filteredBaseTable.push(baseMap[pid]);
        }
    }
    });
    return filteredBaseTable;
}

1 个答案:

答案 0 :(得分:1)

这可以在没有lodash using build-in array reduction的情况下实现。

例如,您可以在reduce数组上调用baseTable,其中对于每次迭代,您都在againstTable中搜索与exid匹配的项。

如果未找到匹配项,请将baseItem添加到您的输出数组(这表示将上述数据中的 exid:“ 2” 添加到结果中的情况)。 / p>

如果找到匹配项,请检查baseItemagainstItem的子级子数组(如果存在),并过滤该子级{{1}所在的baseItem.children数组中的项目}永远不会出现在exid子数组中。如果过滤后的结果非空,请使用过滤后的结果更新againstItem.children子数组并将其添加到您的baseItem

表达这一点的一种方法是代码:

output