如何在JavaScript中过滤嵌套对象数组?现有方法结果不符
解决多层嵌套数组的过滤问题
你当前的代码只完成了一半工作:它确实保留了那些包含符合条件scenario的app对象,但并没有对每个app内部的scenarios数组做过滤——所以每个app里依然保留了所有的scenarios条目,这就是结果不符合预期的核心原因。
要实现你想要的效果,我们需要在筛选出符合条件的app之后,再对每个app的scenarios数组进行二次过滤,只保留那些包含目标contact的scenario。下面是完整的实现代码:
var data = [ { "app": "mail", "scenarios": [ { "name": "", "description": "plugin 1", "contacts": [ { "resourceId": "001", "isPrimary": false } ] }, { "name": "app2", "description": "plugin 2", "contacts": [ { "resourceId": "002", "isPrimary": false } ] } ] }, { "app": "mail2", "scenarios": [ { "name": "app1", "description": "plugin 1", "contacts": [ { "resourceId": "001", "isPrimary": false } ] }, { "name": "app2", "description": "plugin 2", "contacts": [ { "resourceId": "002", "isPrimary": false } ] } ] } ]; const result = data // 第一步:筛选出至少有一个符合条件scenario的app .filter(app => app.scenarios.some(scenario => scenario.contacts.some(contact => contact.resourceId === '001') )) // 第二步:对每个保留的app,过滤其scenarios数组 .map(app => ({ ...app, // 保留app的原有属性(比如app名称) scenarios: app.scenarios.filter(scenario => scenario.contacts.some(contact => contact.resourceId === '001') ) })); console.log(result);
代码说明:
- 第一层过滤(filter):先筛选出所有包含至少一个scenario(该scenario下有resourceId为'001'的contact)的app;
- 映射转换(map):对每个通过筛选的app,我们复制它的原有属性,同时对
scenarios数组做二次过滤,只留下符合条件的scenario条目; - 扩展运算符
...app:确保我们不会修改原始数据,而是返回一个全新的对象数组,避免副作用。
如果你的场景中,某个scenario可能包含多个contacts,并且你需要只保留其中resourceId为'001'的contact条目,可以再对contacts数组做一次过滤:
const result = data .filter(app => app.scenarios.some(scenario => scenario.contacts.some(contact => contact.resourceId === '001') )) .map(app => ({ ...app, scenarios: app.scenarios .filter(scenario => scenario.contacts.some(contact => contact.resourceId === '001')) .map(scenario => ({ ...scenario, contacts: scenario.contacts.filter(contact => contact.resourceId === '001') })) }));
运行第一种代码就能得到你期望的输出结果,第二种则是更严谨的处理方式,适用于更复杂的嵌套数据场景。
内容的提问来源于stack exchange,提问作者Fibi
相关产品推荐
相关产品推荐

