0

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
  },
  ...
]

3 Answers 3

2

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>

Sign up to request clarification or add additional context in comments.

1 Comment

You should change alert to console.log so that running the code snippet doesn't result in 7 alerts
1

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

2 Comments

But what if there's a value in the middle? for example on the 13th? How can I check if there is data on the 13th or not before doing the push. Thanks.
Make multiple calls to fillDates() and concatenate the results. You'll want to modify the function or the concatenations so the intermediate values only appear once in the result.
0
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"}
]

Comments

Your Answer

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