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
},
...
]
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>
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);
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"}
]
Related
I am getting below response from api .
Below is sample respone not real
Each object has createdDate , I have to group value is weekwise wise like.
like 2022-10-01 and 2022-10-02 both are 1st week of Oct , and 2022-10-10 3rd Week of Oct
{
"data": {
"fetchOrdersAndRequest": [
{
"id": "PI786971",
"customerId": [
"C200147"
],
"createdDate": "2022-10-01T04:46:00.126Z",
}
{
"id": "PI786972",
"customerId": [
"C200148"
],
"createdDate": "2022-10-02T04:46:00.126Z",
}
{
"id": "PI786972",
"customerId": [
"C200149"
],
"createdDate": "2022-10-10T04:46:00.126Z",
}
{
"id": "PI786969",
"customerId": [
"C200146"
],
"createdDate": "2022-10-24T04:46:00.126Z",
}
{
"id": "PI786968",
"customerId": [
"C200145"
],
"createdDate": "2022-10-29T04:46:00.126Z",
}
]
}
}
I have to convert the response like below , monthly value I have to convert weekly
{
period:'lastMonth',
Week:[
{
"key":"Week1",
"value" : [{
"id": "PI786971",
"customerId": [
"C200147"
],
"createdDate": "2022-10-01T04:46:00.126Z",
}
{
"id": "PI786972",
"customerId": [
"C200148"
],
"createdDate": "2022-10-02T04:46:00.126Z",
}],
"date": [{2022-10-01}{2022-10-02}]
},
{
"key":"Week2",
"value" : [],
"date:[]
},
{
"key":"Week3",
"value" : [{
"id": "PI786972",
"customerId": [
"C200149"
],
"createdDate": "2022-10-10T04:46:00.126Z",
}],
"date":[{2022-10-10}]
},
{
"key":"Week4",
"value" : [{}],
},
{
"key":"week5",
"value" : []
"date":[{2022-10-24}{2022-10-29}]
},
{
"key":"Week6",
"value" : [],
"date:[]
},
]
// Using below code I am able to filter weeks and my weeks startng from sunday to Saturday , but now I have to puch my api response data matching to dates
fetchMonthWeek = ()=>{
var today = new Date();
const month = today.getMonth() + 1
const year = today.getFullYear()
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
let weeks = {}
var totalDays = new Date(year, month, 0).getDate();
let weekCount = 1
for (let i = 1; i <= totalDays; i++) {
const date = (i < 10 ? '0' + i : i)
const fullDate = (year + '-' + (month < 10 ? '0' + month : month) + '-' + date)
const currentDay = days[new Date(fullDate).getDay()]
if (currentDay === days[0]) weekCount++
const w = 'Week' + weekCount
if (weeks[w]) {
weeks[w].push(fullDate)
} else weeks[w] = [fullDate]
}
console.log(weeks)
let newData = []
for (const w in weeks) {
newData.push({
key: w,
range: {
startDate: weeks[w][0],
endDate: weeks[w][weeks[w].length - 1]
},
value: weeks[w]
})
}
return newData
}
Please help .
Thank you
I have data like this:
[
{
"time": "2021-07-28T18:16:23.994Z"
},
{
"time": "2021-07-29T18:16:23.994Z"
},
{
"time": "2021-08-01T15:01:40.267Z"
},
{
"time": "2021-08-02T15:01:40.267Z"
},
{
"time": "2020-06-09T15:01:40.267Z"
}
]
and I need a method that will return something like this:
{
"2020": { // year
"07/06-13/06": { // dates of the week
"Tue": "2020-06-09T15:01:40.267Z" // day name at key
}
},
"2021": {
"25/07-31/07": {
"Wed": "2021-07-28T18:16:23.994Z",
"Thu": "2021-07-29T18:16:23.994Z"
},
"01/08-07/08": {
"Sun": "2021-08-01T15:01:40.267Z",
"Mon": "2021-08-02T15:01:40.267Z"
}
}
}
I tried to do this with momentjs and lodash/groupby but without success..
Thanks in advance!
a little bit ugly, but works:
const datesArray = [
{
"time": "2021-07-28T18:16:23.994Z"
},
{
"time": "2021-07-29T18:16:23.994Z"
},
{
"time": "2021-08-01T15:01:40.267Z"
},
{
"time": "2021-08-02T15:01:40.267Z"
},
{
"time": "2020-06-09T15:01:40.267Z"
}
]
function getWeeksRange(date) {
const curr = new Date(date.time);
const first = curr.getDate() - curr.getDay();
const last = first + 6;
const format = { year: 'numeric', month: '2-digit', day: '2-digit' };
var firstday = new Date(curr.setDate(first)).toLocaleDateString("he-IL", format);
var lastday = new Date(curr.setDate(last)).toLocaleDateString("he-IL", format);
;
return `${firstday.slice(0, 5).replaceAll('.', '/')}-${lastday.slice(0, 5).replaceAll('.', '/')}`
}
function groupDatesByWeek(dates) {
const groupedDates = {}
dates.forEach(date => {
const range = getWeeksRange(date);
const dayName = new Date(date.time).toString().split(' ')[0]
if (!groupedDates[date.time.split('-')[0]]) {
groupedDates[date.time.split('-')[0]] = {};
groupedDates[date.time.split('-')[0]][range] = {};
} else if (!groupedDates[date.time.split('-')[0]][range]) {
groupedDates[date.time.split('-')[0]][range] = {};
}
groupedDates[date.time.split('-')[0]][range][dayName] = date.time;
})
return groupedDates;
}
console.log(groupDatesByWeek(datesArray))
I have an array that has a object with two properties, 'location' and 'needs'. The needs property has an array of objects with a date and count {date: "2021-06-15", count: 10} so an array would look like this:
{
"location": "NYC",
"needs": [
{
"date": "2021-04-06",
"count": 56
},
{
"date": "2021-04-13",
"count": 10
}
]
}
What I need to do is to use Momentjs to use today's date, figure out the two week period starting from today, and then map the needs-count to the date in the moment loop. If there is a date missing (like in the example below), it should put a 0 as the count
A final array would look like...
{
"location": "NYC",
"needs": [
{
"date": "2021-04-06",
"count": 56 // this had a count in the initial object
},
{
"date": "2021-04-07",
"count": 0
},
{
"date": "2021-04-08",
"count": 0
},
{
"date": "2021-04-09",
"count": 0
},
{
"date": "2021-04-10",
"count": 0
},
{
"date": "2021-04-11",
"count": 0
},
{
"date": "2021-04-12",
"count": 0
},
{
"date": "2021-04-13",
"count": 10 // this had a count in the initial object
},
...
...
...
]
}
In terms of a function, the closest I have got is
let startDay = moment().format('YYYY-MM-DD');
let endDay = moment().add(14, 'days').format('YYYY-MM-DD');
let startDate = moment(startDay);
let endDate = moment(endDay);
let datesBetween = [];
let startingMoment = startDate;
while(startingMoment <= endDate) {
for (let count = 0; count < 15; count ++) {
// at this point im trying to take 'week' which has the location property and needs property and trying to merge them together... but failed miserably.
if (week.needs[count].date === startingMoment) {
datesBetween.push([startingMoment.clone(), week.needs[count].count]);// clone to add new object
startingMoment.add(1, 'days');
} else {
datesBetween.push([startingMoment.clone(), 0]);// clone to add new object
}
}
}
Can someone see where I went so wrong?
const week = {
"location": "NYC",
"needs": [
{
"date": "2021-04-06",
"count": 56
},
{
"date": "2021-04-13",
"count": 10
}
]
}
let current = moment();
const allDates = [];
const FORMAT = 'YYYY-MM-DD';
for (let count = 0; count < 14; count++) {
const found = week.needs.find(i => i.date === current.format(FORMAT));
if (found) {
allDates.push(found);
} else {
allDates.push({
date: current.format(FORMAT),
count: 0,
});
}
current.add(1, 'day');
}
week.needs = allDates;
console.log(week);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous"></script>
You could do something like this :
let dates = {
"location": "NYC",
"needs": [
{
"date": "2021-04-06",
"count": 56
},
{
"date": "2021-04-13",
"count": 10
}
]
};
let day = moment();
for( let i=0; i< 15; i++){
let date = day.add(1, "days").format("YYYY-MM-DD");
console.log(`Looking if ${date} is in array...`)
if(dates.needs.find(obj => obj.date === date)) continue;
console.log(`Adding ${date}`)
dates.needs.push({ date, count : 0 })
}
dates.needs.sort( (a,b) => a.date > b.date ? 1: -1 );
console.log(dates)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
I have javascript array with a teaching hour of a teacher in a day
{
"time": [
{ "start":"10:00","end":"11:00" },
{ "start":"12:00","end":"01:00" },
{ "start":"04:00","end":"06:00" }
]
}
I want to find out free hour of from above array between 10 AM to 6PM
Output array will like this :
{
"time": [
{ "start":"09:00","end":"10:00" },
{ "start":"11:00","end":"12:30" },
{ "start":"01:00","end":"04:00" }
]
}
please help me out to solve this
I have compared end of one object with the start of next object;
based on their difference I decide whether or not to include it in freetime.
let timeObj = {
"time": [
{ "start":"10:00","end":"11:00" },
{ "start":"12:00","end":"01:00" },
{ "start":"04:00","end":"06:00" }
]
}
let newObj = {"time" : []}
let timeArr= timeObj["time"];
for(i=0;i<timeArr.length; i++) {
if(timeArr[i+1] != undefined) {
if(timeArr[i]["end"] != timeArr[i+1]["start"]) {
let freetime = {
"start" : timeArr[i]["end"],
"end" : timeArr[i+1]["start"]
}
newObj["time"].push(freetime);
}
}
}
console.log(newObj)
Try this approach
var obj = {
"time": [{
"start": "10:00",
"end": "11:00"
},
{
"start": "12:00",
"end": "01:00"
},
{
"start": "04:00",
"end": "06:00"
}
]
};
var numConvert = (t) => (t = Number(t.replace(":", ".")), t += t < 10 ? 12 : 0, t);
var output = [];
var output = obj.time.map(s => [numConvert(s.start), numConvert(s.end)])
.reduce(function(a, b, i, arr) {
(i < arr.length - 1) ? (a || []).push([b[1], arr[i + 1][0]]): [];
return a;
}, []).map(s => ({
start: s[0],
end: s[1]
}));
console.log(output);
So I have this array:
var period = [{"total":852, "date":"2016-03"}, {"total":963, "date":"2016-03"},{"total":789,"date":"2016-02"},{"total":456,"date":"2016-04"},{"total":123,"date":"2016-01"},{"total":723,"date":"2016-01"}];
I need to display "total" data grouped by month. Which means I have to sum "total" amount on months that are repeated on the array (2016-03, 2016-01). To find the solution I need to understand why this
for ( var i = 0; i < period.length; i++ ){
if (periodB.indexOf(period[i].date) == -1){
periodB.push(period[i].date);
}
Returns this:
["2016-03", "2016-02", "2016-04", "2016-01"]
While this:
for ( var i = 0; i < period.length; i++ ){
if (periodB.indexOf(period[i].date) == -1){
periodB.push({"date": period[i].date, "total": period[i].total});
}
}
Is returning this:
[{date: "2016-03",total: 1704}, {date: "2016-03", total: 1926}, {date:"2016-02", total: 1578},{date: "2016-04",total: 912}, {date: "2016-01",total: 246}, {date: "2016-01", total: 1446 }]
On the first case repeated "dates" are not being pushed on to periodB array, but then on the second case they are.
You can solve your task using temporary object and one forEach loop
var obj = {};
period.forEach(e => {
var month = e.date.split('-')[1]
obj[month] = obj[month] + e.total || e.total
});
Result will be an object with month as key and total sum as a value
{
'03': 1815,
'02': 789,
'04': 456,
'01': 846
}
Working example:
var period = [{ "total": 852, "date": "2016-03" }, { "total": 963, "date": "2016-03" }, { "total": 789, "date": "2016-02" }, { "total": 456, "date": "2016-04" }, { "total": 123, "date": "2016-01" }, { "total": 723, "date": "2016-01" }];
var obj = {};
period.forEach(e => {
var month = e.date.split('-')[1]
obj[month] = obj[month] + e.total || e.total
});
document.write(JSON.stringify(obj, 0, 2));