使用高阶函数而不是两个循环
Using Higher order functions instead of two loops
我想使用高阶函数,例如 Map、Filter、Reduce。
我的问题是我有一个没有组织的数组,所以我必须执行循环操作才能得到我想要的结果。一个数组有两个字段,一个是 _id
和 totalCount
,这是一个长度最小为 0 到 3 的数组。
totalCount
每次迭代由两个字段组成,一个是 orderstatus,另一个是 total 我想执行正常的 if else 条件,如果 orderstatus 是 "Merchant" 或 "driver" 或 "user" 我想要获取迭代总数并将其存储在我的数组中,如 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 方法执行相同的操作。
您可以将其缩减为两个嵌套的 forEach 循环,并将 orderstatus
作为新的 属性.
的一部分
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);
.as-console-wrapper { max-height: 100% !important; top: 0; }
我会减少并分配它
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);
使用 ES6 语法和 map/reduce 非常容易,
完整功能片段:
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)
https://jsbin.com/kiwalozuxa/edit?html,js,console,output
编辑:The spread operator (...) 用于传播对象的 keys/values(或数组的值)。 totcalcount.reduce
这里return一个对象:
{
x: "x",
y: "y"
}
由于在 javascript 中拥有这种形式的对象在技术上是无效的:
{
a: "a",
b: "b",
{
x: "x",
y: "y"
}
}
我使用扩展运算符将我的 "child" 对象合并到父对象中并生成:
{
a: "a",
b: "b",
x: "x",
y: "y"
}
我在减速器中使用了相同的技术。
我想使用高阶函数,例如 Map、Filter、Reduce。
我的问题是我有一个没有组织的数组,所以我必须执行循环操作才能得到我想要的结果。一个数组有两个字段,一个是 _id
和 totalCount
,这是一个长度最小为 0 到 3 的数组。
totalCount
每次迭代由两个字段组成,一个是 orderstatus,另一个是 total 我想执行正常的 if else 条件,如果 orderstatus 是 "Merchant" 或 "driver" 或 "user" 我想要获取迭代总数并将其存储在我的数组中,如 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 方法执行相同的操作。
您可以将其缩减为两个嵌套的 forEach 循环,并将 orderstatus
作为新的 属性.
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);
.as-console-wrapper { max-height: 100% !important; top: 0; }
我会减少并分配它
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);
使用 ES6 语法和 map/reduce 非常容易, 完整功能片段:
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)
https://jsbin.com/kiwalozuxa/edit?html,js,console,output
编辑:The spread operator (...) 用于传播对象的 keys/values(或数组的值)。 totcalcount.reduce
这里return一个对象:
{
x: "x",
y: "y"
}
由于在 javascript 中拥有这种形式的对象在技术上是无效的:
{
a: "a",
b: "b",
{
x: "x",
y: "y"
}
}
我使用扩展运算符将我的 "child" 对象合并到父对象中并生成:
{
a: "a",
b: "b",
x: "x",
y: "y"
}
我在减速器中使用了相同的技术。