Reputation: 825
I have the following case:
I have an array consisting of all the appointments of the currently logged in user, like this:
this.appointments = [
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-01T17:00:00.000Z",
EndTimezone: null,
Id: 3,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: "FREQ=DAILY;INTERVAL=1;COUNT=5;",
StartTime: "2020-06-01T09:00:00.000Z",
StartTimezone: null,
Subject: "smthng",
km: 88,
week: 23,
_id: "5ecc6f4a08c79c6328974699"
},
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-08T10:30:00.000Z",
EndTimezone: null,
Id: 4,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: null,
StartTime: "2020-06-08T10:00:00.000Z",
StartTimezone: null,
Subject: "smthng" ,
km: 88,
week: 24,
_id: "5ed450d299d5303bd0338a7f"
}
]
What I ultimately want to do is group the array by Client per Week. So accumulate all the time and km
of the appointments (using dayjs library) of one week per client. This is the .reduce
function I have now which groups the array only by Client but not yet per week:
this.appointments.reduce(function (res, value) {
let diff = dayjs(value.EndTime).diff(dayjs(value.StartTime), "hour",true) % 60;
let count;
if(value.RecurrenceRule != null) {
count = parseInt(value.RecurrenceRule.split("COUNT=")[1]);
if(value.RecurrenceException){
if(value.RecurrenceException.match(/,/g) ) {
if(value.RecurrenceException.match(/,/g).length == 0) {
console.log(value.RecurrenceException.match(/,/g).length);
count = count -1;
}
} else if(value.RecurrenceException && value.RecurrenceException.match(/,/g).length == 1) {
console.log(value.RecurrenceException.match(/,/g).length);
count = count -2;
} else if(value.RecurrenceException && value.RecurrenceException.match(/,/g).length == 2) {
console.log(value.RecurrenceException.match(/,/g).length);
count = count -3;
} else
if(value.RecurrenceException && value.RecurrenceException.match(/,/g).length == 3) {
count = count -4;
};
}
}
else if(value.RecurrenceRule == null) {
count = 1;
}
if (!res[value.Client]) {
res[value.Client] = {
week: value.week,
km: value.km * count,
Client: value.Client,
count: count,
difference: diff * count
};
result.push(res[value.Client]);
} else {
res[value.Client].km += value.km * count;
res[value.Client].difference += diff * count;
}
return res;
}, {});
How do I go about this situation? the output now is that instead of creating two rows (week 23 & 24), it sums all the appointments of Steven in week 23 which is incorrect because 0.5 hour took place in another week.
{Client: "Steven"
count: 5
difference: 40.5
km: 528
week: 23}
So the ideal output is:
{
Client: "Steven"
count: 5
difference: 40
km: 440
week: 23
},
{
Client: "Steven"
count: 1
difference: 0.5
km: 88
week: 24
}
You can have rows with the same week number as long as the Client differs.
I hope i made it clear and if you need more context, please mention
Upvotes: 2
Views: 318
Reputation: 4241
Building on @ajai's answer (and using his input first for comparison), hopefully giving you what you need (and using reduce).
const data = [
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-01T17:00:00.000Z",
EndTimezone: null,
Id: 3,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: "FREQ=DAILY;INTERVAL=1;COUNT=5;",
StartTime: "2020-06-01T09:00:00.000Z",
StartTimezone: null,
Subject: "smthng",
km: 88,
week: 23,
_id: "5ecc6f4a08c79c6328974699"
},
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-08T10:30:00.000Z",
EndTimezone: null,
Id: 4,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: null,
StartTime: "2020-06-08T10:00:00.000Z",
StartTimezone: null,
Subject: "smthng" ,
km: 88,
week: 24,
_id: "5ed450d299d5303bd0338a7f"
},
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-01T17:00:00.000Z",
EndTimezone: null,
Id: 3,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: "FREQ=DAILY;INTERVAL=1;COUNT=5;",
StartTime: "2020-06-01T09:00:00.000Z",
StartTimezone: null,
Subject: "smthng",
km: 40,
week: 23,
_id: "5ecc6f4a08c79c6328974699"
},
{
CreatedBy: "bob",
Description: "smtng",
EndTime: "2020-06-01T17:00:00.000Z",
EndTimezone: null,
Id: 3,
IsAllDay: false,
Client: "ajai",
Location: "smthng",
RecurrenceRule: "FREQ=DAILY;INTERVAL=1;COUNT=5;",
StartTime: "2020-06-01T09:00:00.000Z",
StartTimezone: null,
Subject: "smthng",
km: 88,
week: 23,
_id: "5ecc6f4a08c79c6328974699"
}
]
const result = Object.values(data.reduce((aggObj, item) => {
const stringID = `${item.Client}_${item.week}`;
const diff = (new Date(item.EndTime) - new Date(item.StartTime))/(1000*60*60);
const RecurrenceObj = item.RecurrenceRule ?
item.RecurrenceRule.split(";").map(a => {
//console.log(a)
return a.split("=") || ["_", null];
}).reduce((aggObj, [key,val]) => {
aggObj[key] = val;
return aggObj;
})
: {COUNT: 1};
if (aggObj[stringID]){
aggObj[stringID].km += (item.km * RecurrenceObj.COUNT);
aggObj[stringID].count += parseInt(RecurrenceObj.COUNT);
aggObj[stringID].difference += (diff * RecurrenceObj.COUNT);
}
else {
aggObj[stringID] = {
Client: item.Client,
km: item.km * RecurrenceObj.COUNT,
count: parseInt(RecurrenceObj.COUNT),
difference: diff * RecurrenceObj.COUNT,
week: item.week
};
}
return aggObj;
}, {}));
/*
for(var i=0;i<=data.length-1;i++){
let pos = result.findIndex(el=> `${el.Client}-${el.week}`==`${data[i].Client}-${data[i].week}`)
if(pos==-1){
result.push({Client: data[i]['Client'],count: 1,difference: 0,km: data[i]['km'],week: data[i]['week']})
}else{
result[pos]['count'] = result[pos]['count'] + 1;
result[pos]['km'] = result[pos]['km'] + data[i]['km'];
}
}
*/
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
OUTPUT:
[
{
"Client": "Steven",
"km": 640,
"count": 10,
"difference": 80,
"week": 23
},
{
"Client": "Steven",
"km": 88,
"count": 1,
"difference": 0.5,
"week": 24
},
{
"Client": "ajai",
"km": 440,
"count": 5,
"difference": 40,
"week": 23
}
]
Now with your exact input:
const data = [
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-01T17:00:00.000Z",
EndTimezone: null,
Id: 3,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: "FREQ=DAILY;INTERVAL=1;COUNT=5;",
StartTime: "2020-06-01T09:00:00.000Z",
StartTimezone: null,
Subject: "smthng",
km: 88,
week: 23,
_id: "5ecc6f4a08c79c6328974699"
},
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-08T10:30:00.000Z",
EndTimezone: null,
Id: 4,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: null,
StartTime: "2020-06-08T10:00:00.000Z",
StartTimezone: null,
Subject: "smthng" ,
km: 88,
week: 24,
_id: "5ed450d299d5303bd0338a7f"
}
]
const result = Object.values(data.reduce((aggObj, item) => {
const stringID = `${item.Client}_${item.week}`;
const diff = (new Date(item.EndTime) - new Date(item.StartTime))/(1000*60*60);
const RecurrenceObj = item.RecurrenceRule ?
item.RecurrenceRule.split(";").map(a => {
//console.log(a)
return a.split("=") || ["_", null];
}).reduce((aggObj, [key,val]) => {
aggObj[key] = val;
return aggObj;
})
: {COUNT: 1};
if (aggObj[stringID]){
aggObj[stringID].km += (item.km * RecurrenceObj.COUNT);
aggObj[stringID].count += parseInt(RecurrenceObj.COUNT);
aggObj[stringID].difference += (diff * RecurrenceObj.COUNT);
}
else {
aggObj[stringID] = {
Client: item.Client,
km: item.km * RecurrenceObj.COUNT,
count: parseInt(RecurrenceObj.COUNT),
difference: diff * RecurrenceObj.COUNT,
week: item.week
};
}
return aggObj;
}, {}));
/*
for(var i=0;i<=data.length-1;i++){
let pos = result.findIndex(el=> `${el.Client}-${el.week}`==`${data[i].Client}-${data[i].week}`)
if(pos==-1){
result.push({Client: data[i]['Client'],count: 1,difference: 0,km: data[i]['km'],week: data[i]['week']})
}else{
result[pos]['count'] = result[pos]['count'] + 1;
result[pos]['km'] = result[pos]['km'] + data[i]['km'];
}
}
*/
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
OUTPUT:
[
{
"Client": "Steven",
"km": 440,
"count": 5,
"difference": 40,
"week": 23
},
{
"Client": "Steven",
"km": 88,
"count": 1,
"difference": 0.5,
"week": 24
}
]
Upvotes: 1
Reputation: 391
I'm not sure this is what your expectation and I'm not sure what to do with difference just explain me if this is not satisfied.
var data = [
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-01T17:00:00.000Z",
EndTimezone: null,
Id: 3,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: "FREQ=DAILY;INTERVAL=1;COUNT=5;",
StartTime: "2020-06-01T09:00:00.000Z",
StartTimezone: null,
Subject: "smthng",
km: 88,
week: 23,
_id: "5ecc6f4a08c79c6328974699"
},
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-08T10:30:00.000Z",
EndTimezone: null,
Id: 4,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: null,
StartTime: "2020-06-08T10:00:00.000Z",
StartTimezone: null,
Subject: "smthng" ,
km: 88,
week: 24,
_id: "5ed450d299d5303bd0338a7f"
},
{
CreatedBy: "bob",
Description: "smthng",
EndTime: "2020-06-01T17:00:00.000Z",
EndTimezone: null,
Id: 3,
IsAllDay: false,
Client: "Steven",
Location: "smthng",
RecurrenceRule: "FREQ=DAILY;INTERVAL=1;COUNT=5;",
StartTime: "2020-06-01T09:00:00.000Z",
StartTimezone: null,
Subject: "smthng",
km: 40,
week: 23,
_id: "5ecc6f4a08c79c6328974699"
},
{
CreatedBy: "bob",
Description: "smtng",
EndTime: "2020-06-01T17:00:00.000Z",
EndTimezone: null,
Id: 3,
IsAllDay: false,
Client: "ajai",
Location: "smthng",
RecurrenceRule: "FREQ=DAILY;INTERVAL=1;COUNT=5;",
StartTime: "2020-06-01T09:00:00.000Z",
StartTimezone: null,
Subject: "smthng",
km: 88,
week: 23,
_id: "5ecc6f4a08c79c6328974699"
}
]
let result = []
for(var i=0;i<=data.length-1;i++){
let pos = result.findIndex(el=> `${el.Client}-${el.week}`==`${data[i].Client}-${data[i].week}`)
if(pos==-1){
result.push({Client: data[i]['Client'],count: 1,difference: 0,km: data[i]['km'],week: data[i]['week']})
}else{
result[pos]['count'] = result[pos]['count'] + 1;
result[pos]['km'] = result[pos]['km'] + data[i]['km'];
}
}
console.log(result)
Upvotes: 1