对于对象数组中特定日期之间的数字循环求和

时间:2018-10-05 18:46:21

标签: javascript json date for-loop sum

这是来自JSON格式的服务器数据的示例:

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. 如何获取数字的总和。

    我尝试过:

    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);
    }
    

    这会打印数字:1, 3, 6, 10

    我怎么只能得到10而不能得到1, 3, 6

  2. 如何获取特定日期之前/之后的号码。*

    例如,2018-10-3之后的数字之和: 2 + 1 = 3

2 个答案:

答案 0 :(得分:1)

重要提示:请注意@RobG中有关以词法比较ISO 8601日期字符串以避免出现Date.parse问题的能力的评论。请参阅下面更新的答案以反映该评论,原始答案供您参考。

更新:

以下示例与原始示例相比,删除了日期解析步骤。

var 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"
    }
  ]
};

let sum = info.info.reduce((acc, obj) => {
  acc += parseInt(obj.number);
  return acc;
}, 0);

console.log('sum', sum);

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

console.log('sumDate', sumDate);

原始:

您需要parse the date strings进行比较,然后才可以使用reduce。如果您喜欢for循环,请在代码段下方查看一些对原始代码的更正,并提供一些简短的说明(因为它仅适用于所有值的求和-您可以使用与{{1 }}方法。

下面的

reduce仅获得对象数组中所有sum属性的总和(如何使用number的非常简单的示例)。下面的reduce添加了一个sumDate语句,以比较对象数组中的if属性,然后在总和中包含相应的date(只是硬编码了2018-10的日期字符串) -3与其他数据的格式相同,但是您可以将其转换为函数并将日期作为参数传递,并确定是对比较日期之前还是之后的日期求和。

例如:

number

要更正原始的循环尝试,主要问题是您没有增加var 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" } ] }; let sum = info.info.reduce((acc, obj) => { acc += parseInt(obj.number); return acc; }, 0); console.log('sum', sum); let 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('sumDate', sumDate);变量。另外,不要忘记用sum声明要使用的变量(甚至最好用letconst声明)。

var

答案 1 :(得分:1)

  

我怎么只能得到10个而不是1个,3个,6个?

console.log 移出循环。您还可以大大简化代码:

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);

  

如何获取特定日期之前/之后的号码。*

ISO 8601格式的日期字符串可以按字典顺序进行比较。如果以相同格式提供比较日期,请避免使用Date对象和解析:

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

但是,第二个产品可能难以维护。

您还使用了UTC时间戳,因此在与可能会偏移并产生意外结果的“本地”日期进行比较时要小心。