我有一个对象数组& 每个对象都有一个 "开始 "日期& 一个 "结束 "日期。
sortedDateRanges = [
{
id: 1,
start: "2018-01-01",
end: "2018-01-05",
name: "First item"
},
{
id: 2,
start: "2018-01-02",
end: "2018-01-08",
name: "Second item"
},
{
id: 3,
start: "2018-01-06",
end: "2018-01-13",
name: "Third item"
},
{
id: 4,
start: "2018-01-14",
end: "2018-01-14",
name: "Fourth item"
},
{
id: 5,
start: "2018-02-01",
end: "2018-02-15",
name: "Fifth item"
},
]
我需要把这些对象分成几组,每组没有重叠的日期范围。肯定有多个有效的输出。[[{id: 1},{id: 3},{id: 4}], [{id: 2},{id: 5}]]
或 [[{id: 1}, {id: 3}, {id: 5}], [{id: 2}, {id: 4}]]
等。
我目前的解决方案只是将每个范围与前一个范围进行比较,这并不能产生一个 错 解决方案......它不是一个全面的解决方案,像我正在寻找。我目前的解决方案返回 [[{id: 1}],[{id: 2}],[{id: 3}, {id: 4}, {id: 5}]]
export const groupUnoverlappedItems = sortedDateRanges => {
let groups = [];
let rangeIds = [];
sortedDateRanges.map((current, idx, arr) => {
if (idx === 0) {
groups.push([current]);
rangeIds.push(current.id);
// return result;
} else {
let previous = arr[idx -1];
// check for overlap
let previousEnd = (new Date(previous.end)).getTime();
let currentStart = (new Date(current.start)).getTime();
let overlap = (previousEnd >= currentStart);
if (overlap) {
// if overlap, push new group
groups.push([current]);
rangeIds.push(current.id);
} else if (rangeIds.indexOf(current.id) === -1) {
groups[groups.length -1].push(current);
rangeIds.push(current.id);
}
}
});
return groups;
};
我不明白,如果你有一个规则来定义组,或者他们必须形成dinamically。
总之,你为什么不得到最早开始日期的对象,然后用它来创建第一个对象,在第一个组中。
你有了一个起点,然后你就可以找到与你的第一个对象结束日期不重合的最近的开始日期的对象。如果你按顺序进行,一旦你找到了一个重叠的日期,你几乎可以确定那是一个好的日期来形成下一组。
一旦你没有为第一组找到任何其他候选者,那么你可以检查是否有另一个组存在(并且至少有一个对象在其中),然后重复这个过程,直到所有的对象被分配。
我建议使用一个库,比如 日期-fns它可以帮助你用有用的方法来操作日期,也可以定义日期间隔。Javascript对日期有基本的支持,使用一个库可以节省你很多时间。)