如何对比两个数组对象,返回符合条件的新数组对象?

小胖渔
  • 30

我现在有2个数组对象:

let defData = [
            {
                name: 'menu',
                children: [
                    {
                        name: 'menu1',
                        age: 15
                    },
                    {
                        name: 'menu2',
                        age: 16
                    },
                    {
                        name: 'menu3',
                        age: 27
                    }
                ]
            },
            {
                name: 'option',
                children: [
                    {
                        name: 'option1',
                        age: 19
                    },
                    {
                        name: 'option2',
                        age: 22
                    },
                    {
                        name: 'option3',
                        age: 23
                    }
                ]
            },
            {
                name: 'other',
                children: [
                    {
                        name: 'other1',
                        age: 19
                    },
                    {
                        name: 'other2',
                        age: 22
                    },
                    {
                        name: 'other3',
                        age: 23
                    }
                ]
            }
        ]
let bdData = [
            {
                name: 'option',
                children: [
                    {
                        name: 'option1'
                    },
                    {
                        name: 'option3'
                    }
                ]
            },
            {
                name: 'other',
                children: [
                    {
                        name: 'other3'
                    }
                ]
            }
        ]

我想通过 bdData 里面的数据去对比 defData 中的数据。如果 defData 中的 name 等于 bdData 的 name ,就把数据保留,bdData 中没有的数据 要在 defData 中删除。

而且为了可能有层级更深的可能性,我的实现方法是递归,但是效果不对。不知道问题出在哪?

我的实现方法是:

// 传入2个相关数组
function bdFn(def, bd) {
    // 用filter方法过滤
    let res = def.filter(item => {
        // defData 的每一项 和 bdData 的每一项进行比对
        for (let i = 0; i < bd.length; i++) {
            // 如果名字相等就返回 true
            if (item.name === bd[i].name) {
                // 判断是否还有children 
                if(item.children && item.children.length && bd[i].children && bd[i].children.length){
                    // 如果有children 就递归
                    item.children = bdFn(item.children,bd[i].children)
                }
                return true
            }
            // 不符合条件就返回 false
            return false
        }
    })

    console.log(res);
    return res
}

bdFn(defData, bdData)

最后的打印数据不对,我在想,是不是因为 return 语句 把 for 循环给跳出了?

回复
阅读 1.9k
3 个回答
✓ 已被采纳

return false去掉应该就能正常运行了

这种问题你上来不应该直接先写代码的。

这种树式结构的数据,直接用来做查询结果的数据结构会比较麻烦,你应该当先把 bdData 转化为一个 Map 结构,假设 name 是唯一的话,就可以以 namekey,以任意值为 value,之后任意的查找操作时间复杂度均是 O(1)

之后再递归遍历 defDataname 来访问 Map 以确定是否存在该值,如果有,就保留,如果没有,就不保留。

 if(item.children && item.children.length && bd[i].children && bd[i].children.length){
// 如果有children 就递归
    item.children = bdFn(item.children, bd[i].children)
}
return true

这段如果两个children元素不为空就修改了defData,修改了原数组。这样不好。当然也不算错,记得深复制一下,不要改变元数据。
你的问题是return false的位置不对,应该把return false拿到for循环外面。

宣传栏