【问题标题】:How to count occurrences of dates in an array of date ranges: JavaScript如何计算日期范围数组中日期的出现次数:JavaScript
【发布时间】:2020-06-08 05:02:16
【问题描述】:

我有一个 01-01-2020 到 31-12-2020 的日期范围和一个日期范围数组。我想要数组中每个日期的出现与主要范围。

Eg: mainRange = [01-01-2020, 31-12-2020] //range is 366 days

dateRanges =[
  [01-01-2020, 03-01-2020],
  [03-01-2020, 04-01-2020],
  [03-01-2020, 06-01-2020]
];

the output should be =>

countArr = [1,1,3,2,1,1,0,0,......,0]; //array length 366

我不知道如何在 javascript 中实现这一点,我被卡住了。 我尝试了很多搜索,但我只在 excel 公式中找到解决方案。

谢谢

【问题讨论】:

  • 欢迎来到 Stack Overflow!请使用tour(您将获得徽章!)并通读help center,尤其是How do I ask a good question? 您最好的选择是进行研究,search 以获取有关 SO 的相关主题,然后试一试.如果您在进行更多研究和搜索后遇到困难并且无法摆脱困境,请发布您的尝试minimal reproducible example,并具体说明您卡在哪里。人们会很乐意提供帮助。
  • 您的预期输出与您的示例数据不匹配。应该是 1,0,3,1,0,1,0,0...
  • @BrianPatterson 02-01-2020 出现在 dateRanges[0] 中。这就是为什么它不是 0。检查所有范围内的出现。谢谢
  • 啊啊啊,我明白了!感谢您清除它。

标签: javascript arrays date count


【解决方案1】:
var range1 = new Date(2020, 0, 1),
    range2 = new Date(2020, 11, 31),
    dateRanges =[
        [new Date(2020, 0, 1), new Date(2020, 0, 3)],
        [new Date(2020, 0, 3), new Date(2020, 0, 4)],
        [new Date(2020, 0, 3), new Date(2020, 0, 6)],
    ],
    result = [];

while (range1 <= range2) {
    var count = 0;
    dateRanges.forEach(
        function(range) {
            if (range1 >= range[0] && range1 <= range[1]) {
                count++;
            }
        }
    );
    result.push(count);
    range1.setDate(range1.getDate() + 1); //+1 day
}

console.log(result);

【讨论】:

  • 非常感谢。?您的解决方案奏效了。抱歉耽搁了?
【解决方案2】:

以下内容对你有用

let dateRanges = [
  ['01-01-2020', '03-01-2020'],
  ['03-01-2020', '04-01-2020'],
  ['03-01-2020', '06-01-2020']
];
var result = {};
dateRanges.forEach(element => {
		result[element[0]] = result[element[0]] === undefined ? 1 :result[element[0]] + 1 
		result[element[1]] = result[element[1]] === undefined ? 1 :result[element[1]] + 1 
  })
console.log(result);

几点说明:

  1. 日期是字符串,而不是你写的
  2. result 仅包含至少出现一次的日期,因此所有其他日期都为零:
{
  01-01-2020: 1,
  03-01-2020: 3,
  04-01-2020: 1,
  06-01-2020: 1
}

See running code

【讨论】:

  • 如果您想发布运行代码,请在此处作为可运行的 sn-p 进行。它是编辑器中的&lt;&gt; 图标。此外,一个好的答案应该解释代码是如何工作的。在这种情况下,reduce 可能是更好的选择,因为它会创建结果对象并一次性返回。
  • 你能改变它以显示主要范围内的所有日期和旁边的计数吗?谢谢
【解决方案3】:

您可以使用reduce() 来做到这一点:

let dateRanges = [ ['01-01-2020', '03-01-2020'], ['03-01-2020', '04-01-2020'], ['03-01-2020', '06-01-2020']];

datesArray=(generateDatesArray = (start, end)=>{
  for(var arr=[],dt=new Date(start); dt<=end; dt.setDate(dt.getDate()+1)){
     arr.push(new Date(dt).toLocaleDateString());
   }
   return arr;
})(new Date('2020-01-01'),new Date('2020-12-31'));

let dateObj = dateRanges.reduce((acc, dt)=>{
   strtDate = new Date(dt[0].replace(/(\d{2})-(\d{2})/, '$2-$1'));
   endDate = new Date(dt[1].replace(/(\d{2})-(\d{2})/, '$2-$1'));
   dateDiff = Math.ceil(Math.abs(strtDate-endDate)/(1000*60*60*24))+1;
   while(dateDiff--){
	 acc[strtDate.toLocaleDateString()] = acc[strtDate.toLocaleDateString()] || 0;
	 acc[strtDate.toLocaleDateString()]++;
	 let getDt = strtDate.getDate()+1;
	 strtDate.setDate(getDt);
	}
  return acc;
},{});

var result1 = datesArray.map(k=>dateObj[k] || 0);
var result2 = datesArray.map(k=>({[k]:dateObj[k] || 0}));
console.log(result1);
console.log(result2);

现在我们已经准备好带有日期及其出现的日期对象,您可以轻松地从中获取数据。

【讨论】:

  • 您的解决方案简短而美观。你能改变它以显示主要范围内的所有日期和旁边的计数吗?谢谢
  • @AshikPaul 我已经编辑了我的答案,如果有帮助请告诉我。
  • 对不起,我不清楚。我期望结果数组中有 365 个值。我坚持这么多值,因为我必须在图中不包括日期的地方显示 0,这一点非常重要。如果您需要进一步说明,请告诉我。非常感谢。?
猜你喜欢
  • 2021-04-11
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
相关资源
最近更新 更多