简体   繁体   English

按两个元素和总和值对数组对象进行分组(Javascript)

[英]Group array objects by two elements and sum values (Javascript)

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.因此,累积每个客户一周的所有约会时间和km数(使用 dayjs 库)。 This is the .reduce function I have now which groups the array only by Client but not yet per week:这是我现在拥有的.reduce function ,它仅按客户端对数组进行分组,但还不是每周:

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?我该如何 go 这种情况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.现在的 output 不是创建两行(第 23 周和第 24 周),而是将第 23 周 Steven 的所有约会相加,这是不正确的,因为另一周发生了 0.5 小时。

{Client: "Steven"
count: 5
difference: 40.5
km: 528
week: 23}

So the ideal output is:所以理想的 output 是:

{
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我希望我说清楚了,如果您需要更多上下文,请提及

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)

Building on @ajai's answer (and using his input first for comparison), hopefully giving you what you need (and using reduce).基于@ajai 的回答(并首先使用他的输入进行比较),希望能够为您提供所需的内容(并使用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: 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: OUTPUT:

[
  {
    "Client": "Steven",
    "km": 440,
    "count": 5,
    "difference": 40,
    "week": 23
  },
  {
    "Client": "Steven",
    "km": 88,
    "count": 1,
    "difference": 0.5,
    "week": 24
  }
]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM