Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine consecutive dates in javascript?

I have an array of dates such as :

test = [ '2018-07-18', '2018-07-19', '2018-07-21', '2018-07-23', '2018-07-24', '2018-07-26'];

And I want to return an array of sub arrays of consecutive dates like this:

result = [['2018-07-18', '2018-07-19'], ['2018-07-21'], ['2018-07-23', '2018-07-24'], ['2018-07-26']]

I'm trying to write a snippet code:

const moment = require('moment');
let visited = [];
const alpha = test.reduce((accumlator, current_date, current_index, array) => {
    let start_date = current_date;
    let successive_date = array[current_index + 1];
    visited.push(start_date);
    if(successive_date && moment(successive_date).diff(moment(start_date), 'days') === 1  
        && visited.includes(successive_date) === false) {
        accumlator.concat(start_date);
        accumlator.concat(successive_date);
    }
    if(successive_date && moment(successive_date).diff(moment(start_date), 'days') !== 1  
        && visited.includes(successive_date) === false) {
        accumlator.concat(successive_date);
    }
    return accumlator;
}, []);

console.log('alpha: ', alpha);

The result when using concat was:

alpha: []

I used push() and it returns an array such test:

alpha:  [ '2018-07-18','2018-07-19','2018-07-21','2018-07-23','2018-07-23','2018-07-24''2018-07-26' ]

How can I fix this in order to get the result such as mentioned above?

like image 618
Slim Avatar asked Apr 02 '26 05:04

Slim


2 Answers

You can try with:

test.reduce((acc, date) => {
  const group = acc[acc.length - 1];
  if (moment(date).diff(moment(group[group.length - 1] || date), 'days') > 1) {
    acc.push([date])
  } else {
    group.push(date);
  }
  return acc;
}, [[]])

Output:

[
  [
    "2018-07-18",
    "2018-07-19"
  ],
  [
    "2018-07-21"
  ],
  [
    "2018-07-23",
    "2018-07-24"
  ],
  [
    "2018-07-26"
  ]
]
like image 164
hsz Avatar answered Apr 03 '26 19:04

hsz


Th following helps, if the order of the dates in the array is not maintained. For example, '2018-07-18', '2018-07-19', '2018-07-17' are consecutive but scattered at the start and end of the array.

var test = [ '2018-07-18', '2018-07-19', '2018-07-21', '2018-07-23', '2018-07-24', '2018-07-26', '2018-07-17'], dateformat = "YYYY-MM-DD";

var result = test.reduce(function(acc,val){
    var present, date = moment(val,dateformat);
    acc.forEach(function(arr,index){
        if(present) return;
        if(arr.indexOf(date.clone().subtract(1,'day').format(dateformat))>-1 || arr.indexOf(date.clone().add(1,'day').format(dateformat))>-1)
        {
            present = true;
            arr.push(val);
        }
    });
    if(!present) acc.push([val]);
    return acc;
},[]);

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
like image 39
Vignesh Raja Avatar answered Apr 03 '26 17:04

Vignesh Raja



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!