我有一個日期陣列,我試圖將其連接起來以在 javascript 中創建日期范圍。
[更新]:到目前為止,我一直在嘗試將每個月/日/年/小時分成自己的陣列,執行獲取日期范圍的功能,(嘗試)拼接月份,以便它們與更新連接的日期范圍,然后最后需要添加連接日期的所有小時數。
所以起始陣列:
["Nov 23 2021 8 hrs", "Nov 24 2021 8 hrs", "Nov 27 2021 8 hrs", "Dec 3 2021 8 hrs"]
應該:
["Nov 23-24 2021 16 hrs", "Nov 27 2021 8 hrs", "Dec 3 2021 8 hrs"]
我能夠成功地拆分陣列索引,將日期數字推送到一個新陣列中,將它們連接起來,但是我無法弄清楚如何根據第一個日期之后的任何日期擺脫額外的月份索引。
這是一天連接的代碼:
const getDayRanges = (array) => {
var ranges = [],
rstart,
rend;
for (var i = 0; i < array.length; i ) {
rstart = array[i];
rend = rstart;
while (array[i 1] - array[i] == 1) {
rend = array[i 1]; // increment the index if the numbers sequential
i ;
}
ranges.push(rstart == rend ? rstart "" : rstart " to " rend);
}
return ranges;
};
我猜我需要傳入整個陣列并讓它在嵌套的 for 回圈中專門查找 array[i] ,或者可能向該函式添加一個新引數幾個月/年等以比較索引?我有點堅持如何具體做到這一點。
uj5u.com熱心網友回復:
我認為以小時計算日期的邏輯是有缺陷的。如果您單獨保留小時數,例如在 Map 中或二維陣列中,則使用 Date.parse 和 new Date 可以更容易地實作您想要的功能,您可以檢查日期。像這樣的東西:
let date = new Date(Date.parse('Nov 23 2021'))
let date1 = new Date(Date.parse('Nov 24 2021'))
//and use Date methods to compare them
否則,您必須創建一個演算法來匹配正則運算式,以便找到日期和小時數、保留它們、比較它們、組合它們并將它們添加到新串列中。
uj5u.com熱心網友回復:
這是一個經典map/reduce任務。
必須采取以下步驟......
map將原始輸入資料轉換為方便的作業格式,并按日期(和小時)對每個專案進行排序。映射后,
reduce通過嘗試查找連續(或相同)天數的范圍來獲取資料項。在初始 map/reduce 任務(步驟 1 2)之后,
map再次;這次將減少的范圍項資料轉換為特殊的字串化范圍表示或原始輸入格式。
此外 ...
人們不僅要處理一個月內的正常天數范圍,還要處理跨越數月甚至數年的范圍。
一個人必須想出一個正則運算式來提取原始字串
data和hours值....../(?<date>[A-Za-z] \s \d{1,2}\s \d{4})\s (?<hours>\d (?:\.\d )?)\s hrs/
function createWorkDayItem(record) {
const regXWorkDayData
= /(?<date>[A-Za-z] \s \d{1,2}\s \d{4})\s (?<hours>\d (?:\.\d )?)\s hrs/;
const {
date = null,
hours = null,
} = regXWorkDayData.exec(record)?.groups ?? {};
return {
record,
hours: (hours !== null) ? Number(hours) : hours,
date,
time: (date !== null) ? new Date(date).getTime() : date,
};
}
function compareWorkDayItems(a, b) {
return a.time - b.time || b.hours - a.hours;
}
function collectItemOfSameOrConsecutiveDay(listOfRanges, currentItem, idx, arr) {
if (idx >= 1) {
const recentRange = listOfRanges.at(-1);
const recentRangeItem = recentRange.at(-1);
const deltaT = Number(
((currentItem.time - recentRangeItem.time) / 1000 /60 / 60 / 24) // msec => day(s)
.toFixed(4)
);
if (deltaT <= 1/* day*/) {
recentRange.push(currentItem)
} else {
listOfRanges.push([currentItem]);
}
} else {
listOfRanges.push([currentItem]);
}
return listOfRanges;
}
function createWorkDayRangeFormat(rangeItem) {
let result;
if (rangeItem.length === 1) {
result = rangeItem[0].record;
} else {
const totalHours = rangeItem
.reduce((total, { hours }) => total hours, 0);
const [monthStart, dayStart, yearStart]
= rangeItem[0].date.split(/\s /);
const [monthEnd, dayEnd, yearEnd]
= rangeItem.at(-1).date.split(/\s /);
if (yearStart === yearEnd) {
if (monthStart === monthEnd) {
result = [
monthStart,
[dayStart, dayEnd].join('-'),
yearStart,
].join(' ');
} else {
result = [[
[monthStart, dayStart].join(' '),
[monthEnd, dayEnd].join(' '),
].join(' - '), yearEnd].join(' ');
}
} else {
result = [
[monthStart, dayStart, yearStart].join(' '),
[monthEnd, dayEnd, yearEnd].join(' '),
].join(' - ')
}
result = [result, totalHours, 'hrs'].join(' ');
}
return result;
}
const workDayHourList = [
"Nov 23 2021 8 hrs",
"Nov 24 2021 4.5 hrs",
"Nov 24 2021 2.5 hrs",
"Nov 27 2021 8 hrs",
"Dec 3 2021 8 hrs",
"Dec 16 2021 2.25 hrs",
"Dec 18 2021 7.75 hrs",
"Dec 17 2021 6.5 hrs",
"Dec 1 2021 4 hrs",
"Nov 30 2021 6 hrs",
"Dec 31 2020 3.5 hrs",
"Dec 30 2020 4.25 hrs",
"Jan 02 2021 3.75 hrs",
"Jan 01 2021 2.25 hrs",
];
console.log(
'1st ... map the raw input data and sort it by date and hours ...',
workDayHourList
.map(createWorkDayItem)
.sort(compareWorkDayItems)
);
console.log(
'2nd ...after mapping, reduce the data by trying to find ranges of consecutive days ...',
workDayHourList
.map(createWorkDayItem)
.sort(compareWorkDayItems)
.reduce(collectItemOfSameOrConsecutiveDay, [])
);
console.log(
'3rd ... after initial map/reduce, map again, the reduced (range) date into either a special range or into the original input format ...',
workDayHourList
.map(createWorkDayItem)
.sort(compareWorkDayItems)
.reduce(collectItemOfSameOrConsecutiveDay, [])
.map(createWorkDayRangeFormat)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/361806.html
標籤:javascript 数组 映射还原 映射 降低
下一篇:c 從函式中回傳兩個陣列
