简体   繁体   English

将日期范围数组排序为组,其中每个组没有重叠范围(Javascript)

[英]Sort an array of date ranges into groups where each group has no overlapping ranges (Javascript)

I have an Array of objects & each object has a 'start' date & an 'end' date.我有一个对象数组,每个 object 都有一个“开始”日期和一个“结束”日期。

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"
  },
]

I need to sort these objects into groups where each group has NO overlapping date ranges.我需要将这些对象分组,其中每个组没有重叠的日期范围。 There are definitely multiple valid outputs.肯定有多个有效输出。 [[{id: 1},{id: 3},{id: 4}], [{id: 2},{id: 5}]] or [[{id: 1}, {id: 3}, {id: 5}], [{id: 2}, {id: 4}]] etc. [[{id: 1},{id: 3},{id: 4}], [{id: 2},{id: 5}]][[{id: 1}, {id: 3}, {id: 5}], [{id: 2}, {id: 4}]]等。

My current solution is just comparing each range to the previous range which doesn't produce an incorrect solution...it's just not a comprehensive solution like I am looking for.我当前的解决方案只是将每个范围与以前的范围进行比较,这不会产生不正确的解决方案......这不是我正在寻找的全面解决方案。 My current solution returns [[{id: 1}],[{id: 2}],[{id: 3}, {id: 4}, {id: 5}]]我当前的解决方案返回[[{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;
};

I don't understand if you have a rule to define the groups, or they must be formed dinamically.我不明白您是否有定义组的规则,或者它们必须以动态方式形成。

Anyway, why don't you get the object with the earliest start date, and use it to create the first object, in the first group.无论如何,您为什么不获取具有最早开始日期的 object,并用它来创建第一组中的第一个 object。

You have a starting point, then you can find the object with the nearest start date, that doesn't overlap your first object end date.您有一个起点,然后您可以找到具有最近开始日期的 object,它不会与您的第一个 object 结束日期重叠。 If you proceed sequentially, once you find a date that overlaps, you can be almost safe that is the good one to form the next group.如果你按顺序进行,一旦你找到一个重叠的日期,你几乎可以安全地组成下一个小组。

Once you don't find any other candidates for the first group, then you can check if another group exist (and has at least an object in it), then repeat the process, until all objects are allocated.一旦您没有为第一组找到任何其他候选对象,那么您可以检查是否存在另一个组(并且其中至少有一个 object),然后重复该过程,直到分配了所有对象。

May I suggest to use a library, like date-fns , that helps you with useful methods to manipulate dates, and also define date intervals.我可以建议使用一个库,比如date-fns ,它可以帮助您使用有用的方法来操作日期,并定义日期间隔。 Javascript has basic support for dates, using a library can save you a lot of time;) Javascript 对日期有基本的支持,使用库可以为您节省大量时间;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM