1

Here is an example of the data from server in JSON format:

var infom = {
  "info": [
    {
      "date":"2018-10-04T00:00:00.000Z",
      "number":"1"
    },
    {
      "date":"2018-10-03T00:00:00.000Z",
      "number":"2"
    },
    {
      "date":"2018-10-02T00:00:00.000Z",
       "number":"3"
    },
    {
      "date":"2018-10-01T00:00:00.000Z",
      "number":"4"
    }
  ]
};
  1. How can I get the sum of the numbers.

    I have tried:

    info = infom.info;
    var sum = 0;
    for (var i = 0; i < info.length; i++) {
      inf = info[i];
      n1 = parseInt(inf.number);
      console.log(sum+=n1);
    }
    

    This prints the numbers: 1, 3, 6, 10.

    How can I only get the 10 but not 1, 3, 6?

  2. How can I get the numbers before/after a specific date.*

    For example, sum of the numbers after 2018-10-3: 2 + 1 = 3

1
  • for the first question you need to move the console.log outside the for loop. For the second question you need to tuse .filter on the array of elements and keep only those whose date is after/before the one you specify, before performing the addition. Commented Oct 5, 2018 at 19:09

2 Answers 2

1

IMPORTANT: Note the comment from @RobG regarding the ability to compare ISO 8601 date strings lexically to avoid issues with Date.parse. See the updated answer below to reflect that comment, the original answer follows for reference.

UPDATE:

The following example removes the date parsing step when compared to the original.

const info = {"info": [{ "date": "2018-10-04T00:00:00.000Z", "number": "1" }, { "date": "2018-10-03T00:00:00.000Z", "number": "2" }, { "date": "2018-10-02T00:00:00.000Z", "number": "3" }, { "date": "2018-10-01T00:00:00.000Z", "number": "4" } ] };
const sum = info.info.reduce((acc, obj) => {
  acc += parseInt(obj.number);
  return acc;
}, 0);

const sumDate = info.info.reduce((acc, obj) => {
  if (obj.date >= '2018-10-03T00:00:00.000Z') {
    acc += parseInt(obj.number);
  }
  
  return acc;
}, 0);

console.log('sum', sum);
console.log('sumDate', sumDate);

ORIGINAL:

You need to parse the date strings for comparison and then you can just use reduce. If you prefer a for loop, see the corrections to your original code with some quick explanation below the snippet (as it applies to just summing all the values - you could modify the for loop with the same principles as seen below in the reduce approach).

sum below just gets a sum of all the number properties in your array of objects (fairly simple example of how to use reduce). sumDate below adds an if statement to compare the date properties in your array of objects before including the corresponding number in the sum (just hardcoded a date string for 2018-10-3 in the same format as your other data, but you could turn it into a function and pass the date as a parameter as well as determining whether to sum dates before or after the comparison date).

For example:

const info = {"info": [{ "date": "2018-10-04T00:00:00.000Z", "number": "1" }, { "date": "2018-10-03T00:00:00.000Z", "number": "2" }, { "date": "2018-10-02T00:00:00.000Z", "number": "3" }, { "date": "2018-10-01T00:00:00.000Z", "number": "4" } ] };
const sum = info.info.reduce((acc, obj) => {
  acc += parseInt(obj.number);
  return acc;
}, 0);

const sumDate = info.info.reduce((acc, obj) => {
  if (Date.parse(obj.date) >= Date.parse('2018-10-03T00:00:00.000Z')) {
    acc += parseInt(obj.number);
  }
  
  return acc;
}, 0);

console.log('sum', sum);
console.log('sumDate', sumDate);

To correct your original for loop attempt, the primary issue was that you were not incrementing your sum variable. Also, don't forget to declare the variables you are using with var (or even better with let or const).

var info = info.info;
var sum = 0;
for (var i = 0; i < info.length; i++) {
  sum += parseInt(info[i].number);
}

console.log(sum);
// 10
Sign up to request clarification or add additional context in comments.

2 Comments

"You need to parse the date strings", not at all, ISO 8601 format strings can be compared lexically, which avoids the issues of the built-in parser (which the reference you included recommends to avoid).
@RobG - thanks as always for your guidance. The answer has been edited to highlight the date parsing issue for any future readers.
1

How can I only get the 10 but not 1, 3, 6?

Move the console.log out of the loop. You can also greatly simplify the code:

var infom = {"info":[
  {"date":"2018-10-04T00:00:00.000Z","number":"1"},
  {"date":"2018-10-03T00:00:00.000Z","number":"2"},
  {"date":"2018-10-02T00:00:00.000Z","number":"3"},
  {"date":"2018-10-01T00:00:00.000Z","number":"4"}
]};

var info = infom.info;
var sum = 0;

for (var i = 0; i < info.length; i++) {
  sum += parseInt(info[i].number);
}
console.log(sum);

How can I get the numbers before/after a specific date.*

ISO 8601 format date strings can be compared lexicographically. If the comparison date is provided in the same format, you avoid Date objects and parsing:

var infom = {"info":[
  {"date":"2018-10-04T00:00:00.000Z","number":"1"},
  {"date":"2018-10-03T00:00:00.000Z","number":"2"},
  {"date":"2018-10-02T00:00:00.000Z","number":"3"},
  {"date":"2018-10-01T00:00:00.000Z","number":"4"}
]};

function getSumAfter(data, date) {
  return data.reduce(function(acc, obj) {
    if (obj.date.localeCompare(date) > 0) {
      acc += +obj.number;
    }
    return acc;
  }, 0);
}

console.log(getSumAfter(infom.info,'2018-10-02T00:00:00.000Z')); // 3

// Which can be reduced to
function getSumAfter2(data, date) {
  return data.reduce((acc, obj) => obj.date.localeCompare(date) > 0? acc += +obj.number : acc, 0);
}

console.log(getSumAfter2(infom.info,'2018-10-02T00:00:00.000Z')); // 3

However, the second production might be less maintainable.

You're also using UTC timestamps, so be careful when comparing with "local" dates that might be offset and produce unexpected results.

2 Comments

var infom = {"info":[ {"date":"2018-10-04T00:00:00.000Z","number":"1"}, {"date":"2018-10-03T00:00:00.000Z","number":"2", "value":"1"}, {"date":"2018-10-02T00:00:00.000Z","number":"3"}, {"date":"2018-10-01T00:00:00.000Z","number":"4"} ]}; What If I want to get the sum after/before the data where it contains the "value" object in it. Is it possible?
@uhbc—I'd set a flag and only start summing values once an object with a value property, or a value property with certain value, was found.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.