我正在尝试通过重叠对时间段进行分组,但我无法弄清楚如何完成它。
我有一个非常简单的数组,形式为[{start_at: Date, end_at: Date, etc.etc. }]
我把它们放在我看来像这样
<---slot1----><----slot5----><--slot6-->
<--slot2-><--slot4---> <--slot7-->
<----slot3---->
找到直接重叠的插槽并不难,我只是将一个插槽与下一个插槽与(StartA <= EndB) and (EndA >= StartB)
进行比较
from here
现在我想将重叠的插槽(插槽1,2,3,4和5)分组,但不包括插槽6和7,并将这两个放在他们自己的组中。像[[Slot (has 1 through 5)][Slot (has 6 and 7)]]
我现在很想解决这个问题,我希望这里有人可以帮助我。
答案 0 :(得分:1)
我建议创建一个Slot
对象,其中包含:
array
项,start_at
日期,end_at
。通过保持最新的广告位范围,您不必将新项目与每个广告位的项目进行比较。您只需要与插槽本身进行比较。
现在,您必须按start_at
对商品进行排序。然后,您可以通过以下方式减少数组:
Slot
Slot
&#39; s start_at
和end_at
以模仿第一项Slot
的重叠
Slot
项目数组,然后start_at
设置为Slot.start_at
和item2.start_at
end_at
Slot
,重复此Slot
和item3
(等等)示例实现(我建议您根据个人喜好重写它。我没有做任何整洁的类/原型/等等,也没有彻底测试它)
function createSlot(initialItem) {
var slot = {
items: [initialItem],
start: initialItem.start,
end: initialItem.end
};
slot.addItem = function(item) {
slot.items.push(item);
slot.start = Math.min(slot.start, item.start);
slot.end = Math.max(slot.end, item.end);
}
return slot;
};
function itemsOverlap(item1, item2) {
return item1.start <= item2.end &&
item1.end >= item2.start;
};
var slots = [];
var items = randomItems(10);
items.slice(1).reduce(function(currentSlot, item) {
if (itemsOverlap(currentSlot, item)) {
currentSlot.addItem(item);
return currentSlot;
}
slots.push(currentSlot);
return createSlot(item);
}, createSlot(items[0]));
console.log(
slots.map(function(slot) { return slot.items.length; }));
// Create random data
function randomItems(n) {
var arr = [];
for (var i = 0; i < n; i += 1) {
arr.push(generateRandomItem());
}
return arr.sort(function(a, b) { return a.start - b.start; });
};
function randomHourTimespan() {
return Math.random() * 60 * 60 * 1000;
};
function randomHalfDayTimespan() {
return randomHourTimespan() * 12;
};
function generateRandomItem() {
var start = Date.now() + randomHalfDayTimespan();
var end = start + randomHourTimespan();
return { start: new Date(start), end: new Date(end) };
}
&#13;
答案 1 :(得分:0)
我实施了一个简单的算法来对有关start
和end
值的广告位进行分组。
这是一个工作小提琴https://jsfiddle.net/LeoAref/gg6q0mby/,您将找到该分组的视觉演示。
var timeSlots = [
{start: 0, end: 3},
{start: 1, end: 2},
{start: 2, end: 4},
{start: 4, end: 6},
{start: 4, end: 8},
{start: 5, end: 6}
];
timeSlots.forEach((slot, index) => {
var slotElem = document.createElement('div');
slotElem.classList.add('slot');
slotElem.style.top = index * 25 + 'px';
slotElem.style.left = slot.start * 30 + 'px';
slotElem.style.width = (slot.end - slot.start) * 30 + 'px';
document.body.appendChild(slotElem);
});
var groups = [];
timeSlots.forEach(slot => {
added = false;
if (groups.length) {
var index = 0;
do {
group = groups[index];
if (slot.start >= group.start && slot.start < group.end ||
slot.end <= group.end && slot.end > group.start
) {
group.slots.push(slot);
group.start = Math.min(slot.start, group.start);
group.end = Math.max(slot.end, group.end);
added = true;
}
} while (!added && ++index < groups.length);
if (!added) {
groups.push({start: slot.start, end: slot.end, slots: [slot]});
}
} else {
groups.push({start: slot.start, end: slot.end, slots: [slot]});
}
})
groups.forEach(group => {
var groupElem = document.createElement('div');
groupElem.classList.add('group');
groupElem.style.left = group.start * 30 + 'px';
groupElem.style.width = (group.end - group.start) * 30 - 2 + 'px';
document.body.appendChild(groupElem);
})