简体   繁体   English

ES6 减少数组中的嵌套对象

[英]ES6 Reduce nested objects in an array

I've been using map and reduce over some objects and arrays which have been working well so far, however I'm having trouble with one array.我一直在使用 map 并减少了一些对象和 arrays 到目前为止运行良好,但是我遇到了一个阵列的问题。

Example of data here:这里的数据示例:

var arr =
[
[
{
  "id": 6501511,
  "invoiceId": {
    "id": 1043773
  },
  "chargeBandType": "TIME",
  "jobTaskId": {
    "id": 19399852
  },
  "invoicedNet": {
    "amountString": 0,
    "currencyType": "USD"
  },
  "invoicedTaxOneOtherCurrency": null,
  "invoicedTaxOne": {
    "amountString": 0,
    "currencyType": "USD"
  },
  "taxOneRate": 0.1
},
{
  "id": 6501517,
  "invoiceId": {
    "id": 1043773
  },
  "chargeBandType": "TIME",
  "jobTaskId": null,
  "jobExpenseId": null,
  "jobThirdPartyCostId": {
    "id": 20602
  },
  "invoicedNet": {
    "amountString": 0,
    "currencyType": "USD"
  },
  "invoicedTaxOneOtherCurrency": null,
  "invoicedTaxOne": {
    "amountString": 0,
    "currencyType": "USD"
  },
  "taxOneRate": 0.1
},
{
  "id": 6501508,
  "invoiceId": {
    "id": 13773
  },
  "chargeBandType": "TIME",
  "jobTaskId": {
    "id": 19398574
  },
  "invoicedNet": {
    "amountString": 30,
    "currencyType": "USD"
  },
  "invoicedTaxOneOtherCurrency": null,
  "invoicedTaxOne": {
    "amountString": 3,
    "currencyType": "USD"
  },
  "taxOneRate": 0.1
},
{
  "id": 65014,
  "invoiceId": {
    "id": 104
  },
  "chargeBandType": "TIME",
  "jobTaskId": null,
  "jobExpenseId": null,
  "jobThirdPartyCostId": {
    "id": 206
  },
  "invoicedNet": {
    "amountString": 0,
    "currencyType": "USD"
  },
  "invoicedTaxOneOtherCurrency": null,
  "invoicedTaxOne": {
    "amountString": 0,
    "currencyType": "USD"
  },
  "taxOneRate": 0.1
}],
[
{
  "id": 6483,
  "invoiceId": {
    "id": 1042400
  },
  "chargeBandType": "TIME",
  "jobTaskId": {
    "id": 198574
  },
  "invoicedNet": {
    "amountString": 100,
    "currencyType": "USD"
  },
  "invoicedTaxOneOtherCurrency": null,
  "invoicedTaxOne": {
    "amountString": 10,
    "currencyType": "USD"
  },
  "taxOneRate": 0.1
}
]
];

I am trying to reduce the values of invoicedNet.amountString, which would bring a sum of 130 in the case above.我正在尝试减少 invoicedNet.amountString 的值,在上述情况下,这将带来 130 的总和。

I have tried many ways to work this, including functions similar to the below:我尝试了很多方法来解决这个问题,包括类似于以下的功能:

var sum = arr.reduce(function(a, b) {
return a += b.invoicedNet.amountString;
}, 0);

However, no matter how I try this, I keep getting the error:但是,无论我如何尝试,我都会不断收到错误消息:

TypeError: Cannot read property 'amountString' of undefined

(It seems to pick up b.invoicedNet as an object though). (它似乎将 b.invoicedNet 选为 object)。

Could anyone suggest an approach to this?任何人都可以建议一种方法吗?

Thanks谢谢

You need to loop both arrays.您需要循环 arrays。

 var arr = [[{ id: 6501511, invoiceId: { id: 1043773 }, chargeBandType: "TIME", jobTaskId: { id: 19399852 }, invoicedNet: { amountString: 0, currencyType: "USD" }, invoicedTaxOneOtherCurrency: null, invoicedTaxOne: { amountString: 0, currencyType: "USD" }, taxOneRate: 0.1 }, { id: 6501517, invoiceId: { id: 1043773 }, chargeBandType: "TIME", jobTaskId: null, jobExpenseId: null, jobThirdPartyCostId: { id: 20602 }, invoicedNet: { amountString: 0, currencyType: "USD" }, invoicedTaxOneOtherCurrency: null, invoicedTaxOne: { amountString: 0, currencyType: "USD" }, taxOneRate: 0.1 }, { id: 6501508, invoiceId: { id: 13773 }, chargeBandType: "TIME", jobTaskId: { id: 19398574 }, invoicedNet: { amountString: 30, currencyType: "USD" }, invoicedTaxOneOtherCurrency: null, invoicedTaxOne: { amountString: 3, currencyType: "USD" }, taxOneRate: 0.1 }, { id: 65014, invoiceId: { id: 104 }, chargeBandType: "TIME", jobTaskId: null, jobExpenseId: null, jobThirdPartyCostId: { id: 206 }, invoicedNet: { amountString: 0, currencyType: "USD" }, invoicedTaxOneOtherCurrency: null, invoicedTaxOne: { amountString: 0, currencyType: "USD" }, taxOneRate: 0.1 }], [{ id: 6483, invoiceId: { id: 1042400 }, chargeBandType: "TIME", jobTaskId: { id: 198574 }, invoicedNet: { amountString: 100, currencyType: "USD" }, invoicedTaxOneOtherCurrency: null, invoicedTaxOne: { amountString: 10, currencyType: "USD" }, taxOneRate: 0.1 }]], sum = arr.reduce(function (a, b) { b.forEach(function (c) { a += c.invoicedNet.amountString; }); return a; }, 0); console.log(sum);

You can do this quite neatly by flattening the arrays first and then reducing:您可以通过首先展平 arrays 然后减少:

[].concat(...arr)
  .map(invoice => invoice.invoicedNet.amountString)
  .reduce((a, b) => a + b)

Flatten your array, then reduce:展平您的阵列,然后减少:

[].concat(...arr).reduce((a, { invoicedNet: { amountString }}) => a + amountString, 0)

 var arr = [ [ { "id": 6501511, "invoiceId": { "id": 1043773 }, "chargeBandType": "TIME", "jobTaskId": { "id": 19399852 }, "invoicedNet": { "amountString": 0, "currencyType": "USD" }, "invoicedTaxOneOtherCurrency": null, "invoicedTaxOne": { "amountString": 0, "currencyType": "USD" }, "taxOneRate": 0.1 }, { "id": 6501517, "invoiceId": { "id": 1043773 }, "chargeBandType": "TIME", "jobTaskId": null, "jobExpenseId": null, "jobThirdPartyCostId": { "id": 20602 }, "invoicedNet": { "amountString": 0, "currencyType": "USD" }, "invoicedTaxOneOtherCurrency": null, "invoicedTaxOne": { "amountString": 0, "currencyType": "USD" }, "taxOneRate": 0.1 }, { "id": 6501508, "invoiceId": { "id": 13773 }, "chargeBandType": "TIME", "jobTaskId": { "id": 19398574 }, "invoicedNet": { "amountString": 30, "currencyType": "USD" }, "invoicedTaxOneOtherCurrency": null, "invoicedTaxOne": { "amountString": 3, "currencyType": "USD" }, "taxOneRate": 0.1 }, { "id": 65014, "invoiceId": { "id": 104 }, "chargeBandType": "TIME", "jobTaskId": null, "jobExpenseId": null, "jobThirdPartyCostId": { "id": 206 }, "invoicedNet": { "amountString": 0, "currencyType": "USD" }, "invoicedTaxOneOtherCurrency": null, "invoicedTaxOne": { "amountString": 0, "currencyType": "USD" }, "taxOneRate": 0.1 }], [ { "id": 6483, "invoiceId": { "id": 1042400 }, "chargeBandType": "TIME", "jobTaskId": { "id": 198574 }, "invoicedNet": { "amountString": 100, "currencyType": "USD" }, "invoicedTaxOneOtherCurrency": null, "invoicedTaxOne": { "amountString": 10, "currencyType": "USD" }, "taxOneRate": 0.1 } ] ]; console.log([].concat(...arr).reduce((a, { invoicedNet: { amountString }}) => a + amountString, 0))

var sum = arr.reduce(function(a, b) {
return a += b.invoicedNet.amountString;
}, 0);

The above code doesn't work because arr is a multidimensional array.上面的代码不起作用,因为arr是一个多维数组。 Its elements are also an array.它的元素也是一个数组。 You need a nested reducer for this type of array.对于这种类型的数组,您需要一个嵌套的 reducer。 with the arrow function, it can be written as -用箭头 function 可以写成 -

const total = arr.reduce((sum, tasks) => tasks.reduce((previousSum, task) =>
              previousSum + task.invoicedNet.amountString, sum) , 0);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM