I am trying to simplify a list of open times so that there are no overlaps/duplicate information showing (in javascript).
Here is an example of what I am trying to achieve:
The starting array would look something like this:
const mondayHours = [
{ start: "09:00", end: "14:00" },
{ start: "10:00", end: "15:00" },
{ start: "17:00", end: "23:00" },
];
And the data is currently displayed like: Open: 9am-2pm, 10am-3pm, 5pm-11pm
I want the result to return an array for the total open hours like so:
const computedMondayHours = [
{ start: "09:00", end: "15:00" },
{ start: "17:00", end: "23:00" },
];
And so that the data will be displayed like:
Open: 9am-3pm, 5pm-11pm
I have found a solution online that returns the latest open times with the earliest close times, thinking I could convert it for my uses, but that has not worked at all:
const hours = [{
start: "09:00",
end: "14:00"
},
{
start: "10:00",
end: "15:00"
},
{
start: "17:00",
end: "23:00"
}
]
const isBetween = (value, start, end) => value > start && value < end
const computeOpenHours = (dayHours) => {
const index = {}
dayHours.forEach(({
start: aStart,
end: aEnd
}) => {
dayHours.forEach(({
start: bStart,
end: bEnd
}) => {
aStart = isBetween(bStart, aStart, aEnd) && bStart > aStart ? bStart : aStart
aEnd = isBetween(bEnd, aStart, aEnd) && bEnd < aEnd ? bEnd : aEnd
})
const key = `${aStart}-${aEnd}`
const value = {
start: aStart,
end: aEnd
}
index[key] = index[key] || value
})
return Object.keys(index).map(k => index[k])
}
console.log(computeOpenHours(hours))
const hours = [{"start":"09:00","end":"14:00"},
{"start":"10:00","end":"15:00"},
{"start":"17:00","end":"23:00"}]
// returns -ve if a<b, 0 if a=b, +ve if a>b
function cmp(a, b) {
return a.replace(':','') - b.replace(':','')
}
function mergeIfOverlap({start:s1, end:e1}, {start:s2, end:e2}) {
return cmp(s1,s2)<=0 && cmp(e1,s2)>=0
&& {start: s1, end: cmp(e1,e2)>=0 ? e1 : e2}
}
const result = [...hours].sort(({start:a},{start:b})=>cmp(a,b))
.reduce((a,c,_,x,y)=>(
x=a.findIndex(i => y=mergeIfOverlap(i,c)||mergeIfOverlap(c,i)),
y && (a[x]=y) || a.push(c), a), [])
console.log(result)