user4172076
user4172076

Reputation:

How to fill dates in an array containing range of dates?

I have an array of dates containing a count value. e.g.

[
  {
    "date": "2014-11-11T08:00:00.000Z",
    "count": 8
  },
  {
    "date": "2014-11-13T08:00:00.000Z",
    "count": 4
  }
  {
    "date": "2014-11-16T08:00:00.000Z",
    "count": 4
  }
]

How do I fill in the missing dates with count = 0, to produce the following in javascript:

[
  {
    "date": "2014-11-11T08:00:00.000Z",
    "count": 8
  },
  {
    "date": "2014-11-12T08:00:00.000Z",
    "count": 0
  },
  {
    "date": "2014-11-13T08:00:00.000Z",
    "count": 4
  },
  ...
]

Upvotes: 0

Views: 4316

Answers (3)

codeBelt
codeBelt

Reputation: 1805

const models = [
    {
        date: '2018-10-17',
        value: 3,
    },
    {
        date: '2018-10-20',
        value: 4,
    },
    {
        date: '2018-10-21',
        value: 5,
    },
    {
        date: '2018-10-27',
        value: 6,
    },
];

const filledInDates = models.reduce((newArray, currentModel, index, originalArray) => {
    const nextModel = originalArray[index + 1];

    if (nextModel) {
        const currentDate = moment(currentModel.date);
        const daysBetween = moment(nextModel.date).diff(currentDate, 'days');

        const fillerDates = Array.from({length: daysBetween - 1}, (value, dayIndex) => {
            return {
                value: currentModel.value,
                date: moment(currentDate).add(dayIndex + 1, 'days').format('YYYY-MM-DD'),
            };
        });

        newArray.push(currentModel, ...fillerDates);
    } else {
        newArray.push(currentModel);
    }

    return newArray;
}, []);

console.log(filledInDates);

Output:

[
    {value:3, date:"2018-10-17"},
    {value:3, date:"2018-10-18"},
    {value:3, date:"2018-10-19"},
    {value:4, date:"2018-10-20"},
    {value:5, date:"2018-10-21"},
    {value:5, date:"2018-10-22"},
    {value:5, date:"2018-10-23"},
    {value:5, date:"2018-10-24"},
    {value:5, date:"2018-10-25"},
    {value:5, date:"2018-10-26"},
    {value:6, date:"2018-10-27"}
]

Upvotes: 0

Nathan Fisher
Nathan Fisher

Reputation: 7941

as you appear to be using momentjs

the first thing that came to mind was use the moment().add(number, units) and moment().diff(input, units, asFloat)

something like

var data = [
  {
    "date": "2014-11-11T08:00:00.000Z",
    "count": 8
  }, {
    "date": "2014-11-16T08:00:00.000Z",
    "count": 4
  }
];

var startDate = moment(data[0].date);
var endDate = moment(data[1].date);

var days = endDate.diff(startDate, 'd', false);
alert(days);
for (var i = 1; i < days; i++) {
  data.splice(i,0, {"date" : startDate.add(1, 'd').toISOString(), 'count': 0  })
}


for (var i = 0; i < data.length; i++) {
 alert(data[i].date);
}
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>

Upvotes: 2

dug
dug

Reputation: 2335

Try this:

var arr = [
    {
        "date": "2014-11-11T08:00:00.000Z",
        "count": 8
    },
    {
        "date": "2014-11-16T08:00:00.000Z",
        "count": 4
    }
];

function fillDates(start, end) {
    var output = [start];
    var date = new Date(start.date);
    var endDate = new Date(end.date);

    do {
        output.push({
            "date": date.toISOString(),
            "count": 0
        });
        date = new Date(date.getTime());
        date.setDate(date.getDate() + 1);
    } while (date < endDate);

    output.push(end);
    return output;
}

var start = arr[0];
var end = arr[1];
fillDates(start, end);

Upvotes: 1

Related Questions