使用高阶函数而不是两个循环

时间:2017-12-08 13:58:17

标签: javascript arrays reduce higher-order-functions

我想使用更高阶的功能,例如Map,Filter,Reduce 我的问题是我有一个没有组织的数组,所以我不得不执行循环操作来获得我想要的结果。一个数组有两个字段,一个是_idtotalCount,这是一个长度最小为0到3的数组。
totalCount每次迭代包含两个字段,一个是orderstatus,另一个是total,如果orderstatus是“Merchant”或“driver”或“user”,我想执行正常的if else条件我想要获取迭代的总和将它存储在我的数组MerchantCount中。

这是我的代码:

var arr = [{
   _id: "2017-12-08",
   totalcount: [{
     orderstatus: "MERCHANT",
     total: 1
   }]
 },
 {
   _id: "2017-12-02",
   totalcount: [{
     orderstatus: "USER",
     total: 2
   }]
 },
 {
   _id: "2017-12-06",
   totalcount: [{
     orderstatus: "DRIVER",
     total: 1
   }]
 },
 {
   _id: "2017-12-07",
   totalcount: [{
     orderstatus: "MERCHANT",
     total: 3
   }]
 },
 {
   _id: "2017-12-04",
   totalcount: [{
       orderstatus: "DRIVER",
       total: 1
     },
     {
       orderstatus: "MERCHANT",
       total: 2
     },
     {
       orderstatus: "USER",
       total: 1
     }
   ]
 }
]

循环正在执行:

for (let i = 0; i < recentUserCount.length; i++) {
  for (let j = 0; j < recentUserCount[i].totalcount.length; j++) {
    if (recentUserCount[i].totalcount[j].usertype == "DRIVER") {
      recentUserCount[i].DRIVERCount = recentUserCount[i].totalcount[j].total;
    } else if (recentUserCount[i].totalcount[j].usertype == "USER") {
      recentUserCount[i].USERCount = recentUserCount[i].totalcount[j].total;
    } else if (recentUserCount[i].totalcount[j].usertype == "MERCHANT") {
      recentUserCount[i].MERCHANTCount = recentUserCount[i].totalcount[j].total;
    }
  }
}

结果大致如下:

    0 : {_id: "2017-12-08", totalcount: Array(1), MERCHANTCount: 3, $$hashKey: "object:316"}
    1 : {_id: "2017-12-07", totalcount: Array(1), MERCHANTCount: 3, $$hashKey: "object:317"}
    2 : {_id: "2017-12-06", totalcount: Array(1), DRIVERCount: 1, $$hashKey: "object:318"}
    3 : {_id: "2017-12-04", totalcount: Array(3), DRIVERCount: 1, MERCHANTCount: 2, USERCount: 1, …}

我希望使用Map / Filter或Reduce方法执行相同的操作。

3 个答案:

答案 0 :(得分:4)

使用ES6语法和map / reduce非常简单, 功能完整的代码段:

&#13;
&#13;
var arr = [{_id:"2017-12-08",totalcount:[{orderstatus:"MERCHANT",total:1}]},{_id:"2017-12-02",totalcount:[{orderstatus:"USER",total:2}]},{_id:"2017-12-06",totalcount:[{orderstatus:"DRIVER",total:1}]},{_id:"2017-12-07",totalcount:[{orderstatus:"MERCHANT",total:3}]},{_id:"2017-12-04",totalcount:[{orderstatus:"DRIVER",total:1},{orderstatus:"MERCHANT",total:2},{orderstatus:"USER",total:1}]}];

  const result = arr
      .map(({_id, totalcount}) => ({
        totalcount,
        _id,
        ...totalcount.reduce((acc, {orderstatus, total}) => 
          ({...acc, [`${orderstatus}count`]: total}), {})
        }))

console.log(result)
&#13;
&#13;
&#13;

https://jsbin.com/kiwalozuxa/edit?html,js,console,output

编辑:The spread operator(...)用于传播对象的键/值(或数组的值)。 totcalcount.reduce这里返回一个对象:

{
  x: "x",
  y: "y"
}

因为它在javascript中在技术上不具备这种形式的对象:

{
  a: "a",
  b: "b",
  {
    x: "x",
    y: "y"
  }
}

我使用点差运算符合并我的孩子&#34;对象进入父对象并生成:

{
  a: "a",
  b: "b",
  x: "x",
  y: "y"
}

我在减速机中使用相同的技术。

答案 1 :(得分:1)

我会减少并指定它

let res = arr.reduce((a, b) => {
    let totals = b.totalcount.reduce((x, y) => {
        x[y.orderstatus + 'Count'] = (x[y.orderstatus + 'Count'] || 0) + y.total;
        return x;
    }, {});
    return a.concat(Object.assign(b, totals));
}, []);

var arr = [{_id:"2017-12-08",totalcount:[{orderstatus:"MERCHANT",total:1}]},{_id:"2017-12-02",totalcount:[{orderstatus:"USER",total:2}]},{_id:"2017-12-06",totalcount:[{orderstatus:"DRIVER",total:1}]},{_id:"2017-12-07",totalcount:[{orderstatus:"MERCHANT",total:3}]},{_id:"2017-12-04",totalcount:[{orderstatus:"DRIVER",total:1},{orderstatus:"MERCHANT",total:2},{orderstatus:"USER",total:1}]}];

let res = arr.reduce((a, b) => {
    let totals = b.totalcount.reduce((x, y) => {
        x[y.orderstatus + 'Count'] = (x[y.orderstatus + 'Count'] || 0) + y.total;
        return x;
    }, {});
    return a.concat(Object.assign(b, totals));
}, []);

console.log(res);

答案 2 :(得分:0)

您可以将其缩小为两个嵌套的forEach循环,并将orderstatus作为新属性的一部分。

&#13;
&#13;
var totalReference = { MERCHANT: 'MERCHANTCount', USER: 'USERCount', DRIVER: 'DRIVERCount' },
    array = [{ _id: "2017-12-08", totalcount: [{ orderstatus: "MERCHANT", total: 1 }] }, { _id: "2017-12-02", totalcount: [{ orderstatus: "USER", total: 2 }] }, { _id: "2017-12-06", totalcount: [{ orderstatus: "DRIVER", total: 1 }] }, { _id: "2017-12-07", totalcount: [{ orderstatus: "MERCHANT", total: 3 }] }, { _id: "2017-12-04", totalcount: [{ orderstatus: "DRIVER", total: 1 }, { orderstatus: "MERCHANT", total: 2 }, { orderstatus: "USER", total: 1 }] }];

array.forEach(function (o) {
    o.totalcount.forEach(function (p) {
        if (totalReference[p.orderstatus]) {
            o[totalReference[p.orderstatus]] = p.total;
         }
    });
});

console.log(array);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;