簡體   English   中英

按兩個元素和總和值對數組對象進行分組(Javascript)

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

我有以下情況:

我有一個由當前登錄用戶的所有約會組成的數組,如下所示:

 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"
}
  ] 

我最終想要做的是按客戶每周對數組進行分組。 因此,累積每個客戶一周的所有約會時間和km數(使用 dayjs 庫)。 這是我現在擁有的.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;
}, {});

我該如何 go 這種情況現在的 output 不是創建兩行(第 23 周和第 24 周),而是將第 23 周 Steven 的所有約會相加,這是不正確的,因為另一周發生了 0.5 小時。

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

所以理想的 output 是:

{
Client: "Steven"
count: 5
difference: 40
km: 440
week: 23 
},

{
Client: "Steven"
count: 1
difference: 0.5
km: 88
week: 24
}

只要客戶不同,您就可以擁有具有相同周數的行。

我希望我說清楚了,如果您需要更多上下文,請提及

我不確定這是您的期望,我不確定如何處理差異,如果不滿意,請向我解釋。

 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)

基於@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:

[
  {
    "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
  }
]

現在有了您的確切輸入:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM