我有一个如下所示的对象:
let responseData = [
{
"name": "name",
"other": "value",
"anotherField": "blue",
"appRoles": [
{
"code": "roleOne",
"shouldDisplay": true
},
{
"code": "roleTwo",
"shouldDisplay": false
}
]
}
我需要在保留现有属性的同时保持原始结构。我只想删除/过滤掉“shouldDisplay”为假的任何“appRoles”。
以下工作,使用 forEach 和过滤器操作来创建新的对象数组,但是可以更加浓缩这个吗?
let filteredApps;
responseData.forEach((team) => {
let indyTeam = team;
indyTeam.appRoles = team.appRoles.filter((role) => role.shouldDisplay === true);
filteredApps.push(indyTeam);
});
当我使用 map 操作时,我只得到一个已过滤的appRoles数组 - 在每个对象上缺少额外的属性,例如“name”:
let enabledAppRolesOnly =
responseData.map((team) =>
team.appRoles.filter((role) => role.shouldDisplay === true));
答案 0 :(得分:2)
array.map
函数为数组的每个元素调用一个回调函数,然后将其返回值推送到一个新数组。
来自MDN doc:
map按顺序为数组中的每个元素调用一次提供的回调函数,并从结果中构造一个新数组。仅对已分配值的数组的索引(包括undefined)调用回调。它不会被调用缺少数组的元素(即,从未设置过的索引,已删除的索引或从未赋值的索引)。
因此,在您的情况下,由于您返回team.appRoles.filter((role) => role.displayByDefault === true)
这是您的团队数组,因此您只能获得此数据。
你能做的就是这个(为了完全克隆对象):
let responseData = [{
"name": "name",
"appRoles": [
{
"code": "roleOne",
"shouldDisplay": true
},
{
"code": "roleTwo",
"shouldDisplay": false
}
]
}]
let enabledAppRolesOnly = responseData.map(team => {
const appRoles = team.appRoles.filter(role => role.shouldDisplay === true)
return Object.assign({}, team, { appRoles })
});
console.log(enabledAppRolesOnly)
答案 1 :(得分:1)
这将非破坏性地实现您的目标。它将为您构建一个新阵列。
company_id
代码说明 -
map函数迭代整个数组并按指定修改每个项目,这应该是不言而喻的。
这可能是棘手的部分 -
let responseData = [{
name: "name",
appRoles: [{
code: "roleOne",
shouldDisplay: true
}, {
code: "roleTwo",
shouldDisplay: false
}]
}];
let output = responseData.map(o => Object.assign({}, o, {
appRoles: o.appRoles.filter(r => r.shouldDisplay)
}));
console.log(responseData);
console.log(output);
来自文档Object.assign用于复制对象中的值。
o=>Object.assign({}, o, {appRoles: o.appRoles.filter(r=>r.shouldDisplay)})
导致创建一个新对象。{}
导致对象o
中的所有道具都被复制到新创建的对象中。o
属性,并仅保留appRoles
roles
为shouldDisplay
的{{1}}。这正是第三个论点的作用。它修改true
属性并为其赋予新值。现在代码 -
appRoles
不应该太难。
在这里,我们只保留符合我们标准的角色(即o.appRoles.filter(r=>r.shouldDisplay)
应为shouldDisplay
)
如果查看filter函数,它希望回调值返回布尔值,在此基础上它确定是否必须保留值。
因此,甚至不需要以下代码,
true
这就够了,
o.appRoles.filter(r=>r.shouldDisplay===true)
答案 2 :(得分:0)
您可以构建一个新数组,其中只有一部分是有效的chinldren元素。
optimum_list =
{'start_date': datetime.datetime(2017, 8, 25), 'end_date': datetime.datetime(2017, 8, 26), 'value': 52},
{'start_date': datetime.datetime(2017, 8, 27), 'end_date': datetime.datetime(2017, 8, 29), 'value': 12},
{'start_date': datetime.datetime(2017, 9, 1), 'end_date': datetime.datetime(2017, 9, 5), 'value': 20}
cumulative_value_of_sum = 84

let responseData = [{ name: "name", appRoles: [{ code: "roleOne", shouldDisplay: true }, { code: "roleTwo", shouldDisplay: false }] }],
result = responseData.reduce((r, a) => {
var t = a.appRoles.filter(o => o.shouldDisplay);
if (t.length) {
r.push(Object.assign({}, a, { appRoles: t }));
}
return r;
}, []);
console.log(result);

答案 3 :(得分:0)
问题中有一些缺失的信息。我将假设以下内容:
filteredApps
应仅包含至少有一个appRole
用于展示的项目responseData
和filteredApps
包含对相同team
个对象的引用,则可以team
个对象的引用因此,您可以将代码缩减至:
let filteredApps = responseData.filter(team =>
(team.appRoles = team.appRoles.filter(role => role.shouldDisplay)).length;
);
结果将是每个team
在其.shouldDisplay
中仅包含appRoles
个成员,而filteredApps
只会包含至少一个appRole
的成员} shouldDisplay
为true
。