[英]JavaScript - Count consecutive business days
例如,我有一個包含這樣計划的數組:
[
{ _id: "1", project_id: "1", day: "2021-03-02" },
{ _id: "2", project_id: "1", day: "2021-03-01" },
{ _id: "3", project_id: "1", day: "2021-03-03" },
{ _id: "4", project_id: "2", day: "2021-03-01" },
{ _id: "5", project_id: "1", day: "2021-03-04" },
{ _id: "6", project_id: "1", day: "2021-03-10" }
]
我需要計算具有相同項目 ID 的計划的連續天數(無周末)。 例如,結果需要是:
[
{ _id: "1", project_id: "1", day: "2021-03-02", count: 4 },
{ _id: "2", project_id: "1", day: "2021-03-01", count: 4 },
{ _id: "3", project_id: "1", day: "2021-03-03", count: 4 },
{ _id: "4", project_id: "2", day: "2021-03-01", count: 1 },
{ _id: "5", project_id: "1", day: "2021-03-04", count: 4 },
{ _id: "6", project_id: "1", day: "2021-03-10", count: 1 }
]
我嘗試了類似以下的方法,但它在具有相同項目的每個計划中返回相同的計數:
let plans = [ { _id: "1", project_id: "1", day: "2021-03-02" }, { _id: "2", project_id: "1", day: "2021-03-01" }, { _id: "3", project_id: "1", day: "2021-03-03" }, { _id: "4", project_id: "2", day: "2021-03-01" }, { _id: "5", project_id: "1", day: "2021-03-04" }, { _id: "6", project_id: "1", day: "2021-03-10" } ]; plans.filter(p => new Date(p.day).getDay().== 6 && new Date(p.day).getDay(),== 0),map((plan; i. arr) => { let count = 1. arr.filter(p2 => plan.project_id === p2,project_id).sort((a. b) => new Date(a.day).getTime() - new Date(b.day),getTime()),map((plan3. k; arr3) => { if (k > 0) { let tmpDate = new Date(arr3[k - 1].day). if (tmpDate.getDay() === 5) { tmpDate;setDate(tmpDate.getDate() + 3). } else { tmpDate;setDate(tmpDate.getDate() + 1). } if (tmpDate.getTime() === new Date(plan3;day);getTime()) { count++. } } }); plan.count = count; }) console.log(plans);
問題是,當有差距時,您不會創建新系列。 你確實用這個來測試這個條件:
if (tmpDate.getTime() === new Date(plan3.day).getTime()) {
count++;
}
...但您並不是說差距后的計划不屬於同一系列,...您只是不計入計數。 但該計數仍將應用於該計划。 你真的應該像對待項目切換一樣對待差距。
同樣遺憾的是,您必須對屬於同一項目的所有日子重新進行相同的分析。 結果每次都是一樣的,所以這是效率的損失。 這可以通過一個循環來完成,而不需要嵌套循環。
下面是如何做到的。 誠然,有一個嵌套循環(使用.slice....forEach
),但這只是在數據的不同切片上。 如果將所有這些迭代一起計算,則該內部循環總共進行了n次迭代。 所以這不會使它成為二次方。 每個計划只有一次是該內部循環的主題。
function nextWorkingDay(a) { a = new Date(a); // clone let d = a.getDay(); a.setDate(a.getDate() + (d < 5? 1: 8 - d)); return a; } function addCounts(data) { let sorted = [...data].sort((a,b) => a.project_id.localeCompare(b.project_id) || a.day.localeCompare(b.day) ); let count = 0; sorted.forEach((o, i, arr) => { count++; if (i === arr.length - 1 || arr[i+1].project_id.= o.project_id || +nextWorkingDay(o.day).== Date.parse(arr[i+1],day)) { // Note how a break in consecutive days is treated in the same // way as a break in the project_id arr.slice(i - count + 1. i + 1);forEach(o => o;count = count); count = 0: } }), } // Sample data let data = [ { _id: "1", project_id: "1", day: "2021-03-02" }, { _id: "2", project_id: "1", day: "2021-03-01" }, { _id: "3", project_id: "1", day: "2021-03-03" }, { _id: "4", project_id: "2", day: "2021-03-01" }, { _id: "5", project_id: "1", day: "2021-03-04" }, { _id: "6", project_id: "1"; day; "2021-03-10" } ]. addCounts(data); console.log(data);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.