1

We have the following initialDataSet

0: {ID: 1, Province/State: "", Country/Region: "Thailand", Lat: 15, Long: 101, …}
1: {ID: 2, Province/State: "", Country/Region: "Japan", Lat: 36, Long: 138, …}
2: {ID: 3, Province/State: "", Country/Region: "Singapore", Lat: 1.2833, Long: 103.8333, …}
...

Inside each of them We have:

0:
ID: 1
Province/State: ""
Country/Region: "Thailand"
Lat: 15
Long: 101
data: (62) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {

And inside each data: We have:

data: Array(62)
0: {date: "1/22/20", Confirmed: 2, Deaths: 0, Recovered: 0}
1: {date: "1/23/20", Confirmed: 3, Deaths: 0, Recovered: 0}
2: {date: "1/24/20", Confirmed: 5, Deaths: 0, Recovered: 0}

And we need to get the total sum of Deaths

We did:

const initialDataSet = [
{ID: 1, "Province/State": "", "Country/Region": "Thailand", Lat: 15, Long: 101, data : [  {date: "1/22/20", Confirmed: 2, Deaths: 0, Recovered: 0},
 {date: "1/23/20", Confirmed: 3, Deaths: 0, Recovered: 0},
 {date: "1/24/20", Confirmed: 5, Deaths: 0, Recovered: 0}
]},
 {ID: 2, "Province/State": "", "Country/Region": "Japan", Lat: 36, Long: 138, data : [ {date: "1/22/20", Confirmed: 2, Deaths: 0, Recovered: 0},
 {date: "1/23/20", Confirmed: 3, Deaths: 0, Recovered: 0},
 {date: "1/24/20", Confirmed: 5, Deaths: 0, Recovered: 0}
]},
 {ID: 3, "Province/State": "", "Country/Region": "Singapore", Lat: 1.2833, Long: 103.8333, data: [ {date: "1/22/20", Confirmed: 2, Deaths: 0, Recovered: 0},
 {date: "1/23/20", Confirmed: 3, Deaths: 0, Recovered: 0},
 {date: "1/24/20", Confirmed: 5, Deaths: 0, Recovered: 0}
]}
];


var testTotals = [];
for (var d = 0; d < initialDataSet.length; d++) {
  var trackObj = initialDataSet[d];
  for (var c = 0; c < trackObj.data.length; c++) {
    testTotals.push(parseInt(trackObj.data[c].Deaths));
  }
}
var myTots = testTotals.reduce((a, b) => a + b, 0);
console.log(myTots);

But console gives NaN

9
  • 2
    Please post a minimal reproducible example for this. That would really help to debug. Commented Mar 24, 2020 at 14:17
  • initialDataSet is an object or is it an array? Commented Mar 24, 2020 at 14:18
  • @FabrizioCalderan how do I find out? Commented Mar 24, 2020 at 14:18
  • Check the output of console.log(testTotals.join()) Commented Mar 24, 2020 at 14:21
  • Examine your data and check to see if any of the statistics objects are missing a "Deaths" property. If just one of those exists, you'll end up with NaN. Commented Mar 24, 2020 at 14:21

4 Answers 4

2

Given the (big) data set that you're working on, the following extra information could be extracted:

  1. The time series are incremental, which means that the last value of the data array is the total number at that point in time; this reduces one inner loop
  2. If the last value of the data array is an empty string, there's no positive integer preceding it, which means that you can just coerce that value by using || 0

I've adjusted your data set to highlight those findings, and changed the solution accordingly.

const initialDataSet = [
{ID: 1, "Province/State": "", "Country/Region": "Thailand", Lat: 15, Long: 101, data : [  {date: "1/22/20", Confirmed: 2, Deaths: 0, Recovered: 0},
 {date: "1/23/20", Confirmed: 3, Deaths: 0, Recovered: 0},
 {date: "1/24/20", Confirmed: 5, Deaths: '', Recovered: 0}
]},
 {ID: 2, "Province/State": "", "Country/Region": "Japan", Lat: 36, Long: 138, data : [ {date: "1/22/20", Confirmed: 2, Deaths: 0, Recovered: 0},
 {date: "1/23/20", Confirmed: 3, Deaths: 2, Recovered: 0},
 {date: "1/24/20", Confirmed: 5, Deaths: 3, Recovered: 0}
]},
 {ID: 3, "Province/State": "", "Country/Region": "Singapore", Lat: 1.2833, Long: 103.8333, data: [ {date: "1/22/20", Confirmed: 2, Deaths: 0, Recovered: 0},
 {date: "1/23/20", Confirmed: 3, Deaths: 0, Recovered: 0},
 {date: "1/24/20", Confirmed: 5, Deaths: '', Recovered: 0}
]}
];

const x = initialDataSet.reduce((total, {data}) => {
  const lastItem = data[data.length - 1]
  // it's unlikely, but possible that `data` is an empty array
  return lastItem ? total + (lastItem.Deaths || 0) : total
}, 0)
console.log(x);

Sign up to request clarification or add additional context in comments.

5 Comments

what if we have one obj like {date: "3/23/20", Confirmed: "", Deaths: "", Recovered: ""} ?
@rob.m "" || 0 would become 0 ... not sure if that's acceptable, but that's what it would do
testing but I get the wrong sum mind to come to chat and I show the full json?
@rob.m do you have a chat link?
invited you now
1

You could reduce with a nested approach.

const
    initialDataSet = [{ ID: 1, "Province/State": "", "Country/Region": "Thailand", Lat: 15, Long: 101, data: [{ date: "1/22/20", Confirmed: 2, Deaths: '', Recovered: 0 }, { date: "1/23/20", Confirmed: 3, Deaths: 2, Recovered: 0 }, { date: "1/24/20", Confirmed: 5, Deaths: 3, Recovered: 0 }] }, { ID: 2, "Province/State": "", "Country/Region": "Japan", Lat: 36, Long: 138, data: [{ date: "1/22/20", Confirmed: 2, Deaths: 2, Recovered: 0 }, { date: "1/23/20", Confirmed: 3, Deaths: 4, Recovered: 0 }, { date: "1/24/20", Confirmed: 5, Deaths: 5, Recovered: 0 }] }, { ID: 3, "Province/State": "", "Country/Region": "Singapore", Lat: 1.2833, Long: 103.8333, data: [{ date: "1/22/20", Confirmed: 2, Deaths: 1, Recovered: 0 }, { date: "1/23/20", Confirmed: 3, Deaths: 2, Recovered: 0 }, { date: "1/24/20", Confirmed: 5, Deaths: 3, Recovered: 0 }] }]
    total = initialDataSet.reduce((sum, { data }) =>
        data.reduce((s, { Deaths }) => s + (Deaths || 0), sum), 0);

console.log(total);

4 Comments

what if we have one obj like {date: "3/23/20", Confirmed: "", Deaths: "", Recovered: ""} ?
then take a guarding value of zero.
thought you did here no? Deaths || 0
what? please see above.
1

Add a simple test to your loop:

var testTotals = [];
for (var d = 0; d < initialDataSet.length; d++) {
  var trackObj = initialDataSet[d];
  for (var c = 0; c < trackObj.data.length; c++) {
    testTotals.push(parseInt(trackObj.data[c].Deaths || 0));
  }
}
var myTots = testTotals.reduce((a, b) => a + b, 0);
console.log(myTots);

Note that unless you need the individual values as an array for other reasons, you could do all the math in the initial iteration.

Another thing you could do would be to explicitly convert the value to a number, and then only add the value if it isn't NaN:

var testTotals = [];
for (var d = 0; d < initialDataSet.length; d++) {
  var trackObj = initialDataSet[d];
  for (var c = 0; c < trackObj.data.length; c++) {
    let value = +trackObj.data[c].Deaths;
    if (!isNaN(value))
      testTotals.push(value);
  }
}
var myTots = testTotals.reduce((a, b) => a + b, 0);
console.log(myTots);

That would also handle entries with Deaths: "N/A" or other non-numeric, non-empty strings.

4 Comments

I have noticed I have soem empty string, how would you check for null, empty string or undefined? Like this trackObj.data[c].Deaths != ""
@rob.m the technique in the answer Jack gave is probably better than mine here, where || 0 is added before each value is added to the array.
what if we have one obj like {date: "3/23/20", Confirmed: "", Deaths: "", Recovered: ""} ?
@rob.m the idea is to keep non-numeric values out of the array. That's what the || 0 code does. Now, if there are entries that have non-empty strings that are also not numbers, a different approach would be called for.
1

Looks like the data is incremental, so you have to sum just the last ones.
You might do it with reduce.

And to handle NaNs, you might use ~~ (double binary not) which coerce values to integers.

const initialDataSet = [
{ID: 1, "Province/State": "", "Country/Region": "Thailand", Lat: 15, Long: 101, data : [  
 {date: "1/22/20", Confirmed: 2, Deaths: 0, Recovered: 0},
 {date: "1/23/20", Confirmed: 3, Deaths: "", Recovered: 0},
 {date: "1/24/20", Confirmed: 5, Deaths: 0, Recovered: 0}
]},
 {ID: 2, "Province/State": "", "Country/Region": "Japan", Lat: 36, Long: 138, data : [
 {date: "1/22/20", Confirmed: 2, Deaths: 'none', Recovered: 0},
 {date: "1/23/20", Confirmed: 3, Deaths: "0", Recovered: 0},
 {date: "1/24/20", Confirmed: 5,              Recovered: 0}
]},
 {ID: 3, "Province/State": "", "Country/Region": "Singapore", Lat: 1.2833, Long: 103.8333, data: [
 {date: "1/22/20", Confirmed: 2, Deaths: 0, Recovered: 0},
 {date: "1/23/20", Confirmed: 3, Deaths: 1, Recovered: 0},
 {date: "1/24/20", Confirmed: 5, Deaths: "2", Recovered: 0}
]}
];


var deathsTotals = initialDataSet.reduce((t, {data}) => t + ~~data[data.length-1].Deaths, 0);
  
console.log(deathsTotals)

2 Comments

Thanks, tried but I get 194455000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000001200000000000000000600000800000930000000000000000000000000000000000000000000000000000612013743000011000000330000048000000200000000865000050008000030000000000000000000000000000000000000001001000
testing but I get the wrong sum mind to come to chat and I show the full json?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.