基于嵌入式数组的JavaScript对象数组过滤
我有一个如下所示的对象:基于嵌入式数组的JavaScript对象数组过滤,javascript,arrays,ecmascript-6,Javascript,Arrays,Ecmascript 6,我有一个如下所示的对象: let responseData = [ { "name": "name", "other": "value", "anotherField": "blue", "appRoles": [ { "code": "roleOne", "shouldDisplay": true }, { "code": "roleTwo", "shouldDisp
let responseData = [
{
"name": "name",
"other": "value",
"anotherField": "blue",
"appRoles": [
{
"code": "roleOne",
"shouldDisplay": true
},
{
"code": "roleTwo",
"shouldDisplay": false
}
]
}
我需要保持原有的结构,同时保留现有的财产。我只想删除/过滤掉任何“shouldDisplay”为false的“appRoles”
下面使用forEach和filter操作创建一个新的对象数组是可行的,但是有可能进一步压缩它吗
let filteredApps;
responseData.forEach((team) => {
let indyTeam = team;
indyTeam.appRoles = team.appRoles.filter((role) => role.shouldDisplay === true);
filteredApps.push(indyTeam);
});
当我使用映射操作时,我只得到一个过滤的方法数组-缺少每个对象的额外属性,例如“name”:
函数为数组的每个元素调用回调,然后将其返回值推送到新数组
从MDN文档:
map为数组中的每个元素按顺序调用一次提供的回调函数,并根据结果构造一个新数组。回调仅对具有赋值(包括未定义)的数组索引调用。对于数组中缺少的元素(即从未设置、已删除或从未赋值的索引),不会调用它
因此,在您的例子中,由于您返回team.approvles.filter((role)=>role.displayberdefault==true)
这是您的团队数组,所以您只得到这个
您可以这样做(为了完全克隆对象):
let responseData=[{
“名称”:“名称”,
“批准”:[
{
“代码”:“roleOne”,
“应显示”:true
},
{
“代码”:“roleTwo”,
“应显示”:false
}
]
}]
让enabledapresonly=responseData.map(团队=>{
const appRoles=team.appRoles.filter(角色=>role.shouldDisplay===true)
返回Object.assign({},team,{appRoles})
});
log(enabledAppProlesOnly)
您可以构建一个新数组,其中只包含部分有效的chinldren元素
let responseData=[{name:“name”,appRoles:[{code:“roleOne”,shouldDisplay:true},{code:“roleTwo”,shouldDisplay:false}]},
结果=响应数据减少((r,a)=>{
var t=a.approvles.filter(o=>o.shouldDisplay);
if(t.长度){
r、 push(Object.assign({},a,{appRoles:t}));
}
返回r;
}, []);
控制台日志(结果)代码>
.as控制台包装{max height:100%!important;top:0;}
问题中缺少一些信息。我将假设如下:
let responseData = [
{
"name": "name",
"other": "value",
"anotherField": "blue",
"appRoles": [
{
"code": "roleOne",
"shouldDisplay": true
},
{
"code": "roleTwo",
"shouldDisplay": false
}
]
}
filteredApps
应仅包含至少有一个appRole
可供显示的项目
- 如果
responseData
和filteredApps
包含对相同团队
对象的引用,则可以
- 没有其他对
team
对象的引用需要保持原始数据不受影响
因此,您可以将代码简化为:
let filteredApps = responseData.filter(team =>
(team.appRoles = team.appRoles.filter(role => role.shouldDisplay)).length;
);
结果将是每个团队
将只有。应在其批准中显示成员
,filteredApps
将只有至少一个批准
且应显示
为真
的团队。这将以非破坏性方式实现您的目标。它将为您构建一个新阵列
let responseData=[{
姓名:“姓名”,
批准:[{
代码:“roleOne”,
应该显示:true
}, {
代码:“roleTwo”,
shouldDisplay:false
}]
}];
让output=responseData.map(o=>Object.assign({},o{
appRoles:o.appRoles.filter(r=>r.shouldDisplay)
}));
控制台日志(responseData);
控制台日志(输出)
是否仅当Approvles
中有元素时才获取外部对象?尚不清楚将团队
包含到filteredApps
中的标准是什么。另外,filteredApps
是未定义的
,您正在使用一个名为displayberdefault
的属性,该属性不存在代码>实际上没有做任何有用的事情。你在那里期待什么?团队的深度副本
?@spanky yep!我需要所有团队数据,只需轻微筛选-删除displayByDefault字段为false的角色。因此,筛选的Approvles
应仅从filteredApps
中查看,而不应从原始responseData
中查看?换句话说,responseData
应该完全不受影响?啊,好的。这很有效。不过我还有其他财产。是否有任何方法可以自动返回它们,而无需指定它们(正如您在上面对“name”所做的那样)?那太好了,尤其是如果随着时间的推移添加了新字段。是的,我可以查看属性以给出最相应的方式吗?更新了问题,包含更多字段。。。那么有没有办法不一一说明呢?因此避免:返回{name:team.name,other:team.other,另一个字段:team.other};我更新了我的答案,但要小心,如果您担心嵌套属性检查,这可能会起作用,但我正在尝试在不更改原始数组的情况下维护它(即,将结果分配给新变量),为什么在明确执行映射
操作时使用reduce?我只使用外部元素,如果内部是一个积极的角色。当您更新您的答案以包括Object.assign
时,我已经写了我的答案,包括Object.assign
。按照这个逻辑,我可以说你重复了我的答案,但你先回答了。你的回答被接受了。没关系。尤利西斯(在一开始)有一个更完整的答案,也是我碰巧看到并首先解决的答案。亚西尔,你赢了!非常感谢。