【问题标题】:refactor map, reduce and double for loop - javascript es6重构映射、减少和加倍 for 循环 - javascript es6
【发布时间】:2020-01-22 21:32:44
【问题描述】:

我有一个 JavaScript 对象,比如说parentObj

如何改进以下代码。我有一个reduce、一个map 和一个double for loop

[
   {
      NAME: 'SOMENAME',
      ID: '1',
      FROM: '20191223',
      TO: '99991231'
    },

   {
      NAME: 'SOMENAME',
      ID: '2',
      FROM: '20191223',
      TO: '99991231'
   },

   {
      NAME: 'SOMENAME',
      ID: '3',
      FROM: '20191223',
      TO: '99991231'
   }
]

我创建了一个新对象。

  const newObj = .reduce(
    function (obj, item) {
      obj[item.NAME] = obj[item.NAME] || [];
      obj[item.NAME].push(item.ID);
      return obj;
    },
    {}
  );

然后从中取出一个新的对象数组。

  const newObjArr = Object.keys(newObj ).map(function (key) {
        return { NAME: key, ID: newObj [key] };
      });

然后是一个双循环。

      for (let item1 of newObjArr) {
        for (let item2 of parentObj) {
          if (item1.NAME=== item2.NAME) {
            finalObjArr.push({ NAME: item1.NAME, ID: item1.ID, FROM: item2.FROM, TO: item2.TO});
          }
        }
      }

我的最终输出:

[
   {
      NAME: 'SOMENAME',
      ID: [1, 2, 3],
      FROM: '20191223',
      TO: '99991231'
   },
   ...
]

【问题讨论】:

  • 这听起来像是您想要转换输入。你能同时提供示例输入和预期输出吗?
  • 你想在第二个代码 sn-p 中减少什么?
  • @Ben 更新了....
  • 您确定要让输出中的一些ID 条目共享相同的数组对象吗?

标签: javascript ecmascript-6


【解决方案1】:

您已经拥有newObj,您可以在其中按名称查找内容。无需构建 newObjArr 并遍历它以按名称搜索。随便写

for (const item2 of parentObj) {
  const item1_NAME = item2.NAME;
  const item1_IDs = newObj[item1_NAME];
  finalObjArr.push({ NAME: item1_NAME, ID: item1_IDs, FROM: item2.FROM, TO: item2.TO});
}

鉴于您在 cmets 中的更新,我建议您实际上将包含所有信息的对象放在 newObj 中,然后您只需要获取其值作为数组:

const newObj = parentObj.reduce((obj, item) => {
  if (!(item.NAME in obj))
    obj[item.NAME] = { NAME: item.NAME, ID: [], FROM: item.FROM, TO: item.TO };
  obj[item.NAME].ID.push(item.ID);
  return obj;
}, {});
const finalObjArr = Object.values(newObj);

【讨论】:

  • parentObj 数组中的所有条目与连续项的NAME 值不同时,此输出的顺序可能与 OP 的输出不同。
  • @trincot 啊,那是真的。如果订单很重要,他们不应该使用Object.keys :-)
  • @Bergi,如何确保不输入重复的NAME
  • @user2281858 如果item1_IDs数组有多个元素,则存在重复名称
  • @Bergi 我可以不从parentObject 创建final array of object 这样我也可以避免重复,因为在reduce 函数中,我确保没有重复。
【解决方案2】:

您可以使用以下内容:

// sample data
let parentObj = [{NAME: 'SOMENAME',ID: '1',FROM: '20171223',TO: '99991231'},{NAME: 'SOMENAME',ID: '2',FROM: '20181223',TO: '99991231'},{NAME: 'SOMENAME',ID: '3',FROM: '20191223',TO: '99991231'}];

let map = new Map(parentObj.map(o => [o.NAME, []]));
parentObj.forEach(o => map.get(o.NAME).push(o));
let finalObjArr = Array.from(map.values(), arr => 
     arr.map(o => ({...o, ID: arr.map(o => o.ID)}))
).flat();

console.log(finalObjArr);

与您自己的解决方案的不同之处在于,输出中的每个ID 数组现在都是独立的。因此,如果您要对其中一个进行变异,则该更改不会显示在另一个对象中。

我使用了array.flat(),它不在 ES6 中(你提到了 ES6)。如果这是个问题,请改用[].concat(...array)

【讨论】:

    【解决方案3】:

    这可能是你想要的。

    const parentObj = [{
        NAME: 'SOMENAME',
        ID: '1',
        FROM: '20191223',
        TO: '99991231'
    },
    {
        NAME: 'SOMENAME',
        ID: '2',
        FROM: '20191223',
        TO: '99991231'
    },
    {
        NAME: 'SOMENAME',
        ID: '3',
        FROM: '20191223',
        TO: '99991231'
    }]
    
    const ids = parentObj.reduce((p,{NAME, ID})=>
            ((p[NAME] || (p[NAME] = [])),
             (p[NAME].push(ID)), p), {})
    
    console.log(parentObj.map(({NAME, FROM, TO})=>
            ({NAME, ID: ids[NAME], FROM, TO})))

    或者这可能是你想要的。根据您对另一个答案的评论,可能存在歧义:

    const parentObj = [{
        NAME: 'SOMENAME',
        ID: '1',
        FROM: '20191223',
        TO: '99991231'
    },
    {
        NAME: 'SOMENAME',
        ID: '2',
        FROM: '20191223',
        TO: '99991231'
    },
    {
        NAME: 'SOMENAME',
        ID: '3',
        FROM: '20191223',
        TO: '99991231'
    }]
    
    console.log(Object.values(parentObj.reduce(
        (p,{NAME, ID, FROM, TO})=>
            ((p[NAME] || (p[NAME] = {NAME, ID: [], FROM, TO})),
             (p[NAME]['ID'].push(ID)), p), {})))

    【讨论】:

    • 我无法运行 [...p[NAME]。它说这种语法需要一个名为 _spreadArrays 的导入助手
    猜你喜欢
    • 2011-04-27
    • 2018-03-03
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 2011-12-22
    • 2011-10-29
    • 1970-01-01
    相关资源
    最近更新 更多