嵌入式数组

时间:2017-08-15 18:17:37

标签: javascript arrays ecmascript-6

我有一个如下所示的对象:

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));

4 个答案:

答案 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

map函数迭代整个数组并按指定修改每个项目,这应该是不言而喻的。

Object.assign

这可能是棘手的部分 -

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 rolesshouldDisplay的{​​{1}}。这正是第三个论点的作用。它修改true属性并为其赋予新值。

filter

现在代码 -

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用于展示的项目
  • 如果responseDatafilteredApps包含对相同team个对象的引用,则可以
  • 没有其他对需要保持原始数据不受影响的team个对象的引用

因此,您可以将代码缩减至:

let filteredApps = responseData.filter(team =>
   (team.appRoles = team.appRoles.filter(role => role.shouldDisplay)).length;
);

结果将是每个team在其.shouldDisplay中仅包含appRoles个成员,而filteredApps只会包含至少一个appRole的成员} shouldDisplaytrue