1

Working in Python, I've got a list of dicts containing a start date, end date and a list of values.

These may overlap and I need to break them into unique time periods, and merge the values from any overlapping period.

For example:

[
    # Cover the space of 1 year
    {
        "values": ["a", "b", "c"],
        "start": "2023-01-01T00:00:00+00:00",
        "end": "2024-01-01T00:00:00+00:00",
    },
    # Overlapping month with new values
    {
        "values": ["d", "e"],
        "start": "2023-02-01T00:00:00+00:00",
        "end": "2023-03-01T00:00:00+00:00",
    },
]

Should output:

[
    {
        "values": ["a", "b", "c"],
        "start": "2023-01-01T00:00:00+00:00",
        "end": "2023-02-01T00:00:00+00:00",
    },
    {
        "values": ["a", "b", "c", "d", "e"],
        "start": "2023-02-01T00:00:00+00:00",
        "end": "2022-03-01T00:00:00+00:00",
    },
    {
        "values": ["d", "e"],
        "start": "2023-03-01T00:00:00+00:00",
        "end": "2024-01-01T00:00:00+00:00",
    },
]

I've been able to merge all the dates down to a single date range of the min/max, but I'm completely stumped on how I can dynamically work out the overlapping values.

1 Answer 1

0

Just sort the list by start date and then iterating through the sorted list to find and merge overlapping periods and you will obtain the desired result.

edit: if you also want to keep track of the time windows during which these values are active we can modify our code like this:

def merge_overlapping_dates(input_list: List[Dict]) -> List[Dict]:
    # Sort the list by start date
    input_list.sort(key=lambda x: parse_date(x["start"]))

    result = []
    for item in input_list:
        # Parse dates
        start = parse_date(item["start"])
        end = parse_date(item["end"])

        # Check if the current item overlaps with the previous item in the result
        if result and start <= parse_date(result[-1]["end"]):
            # Merge overlapping values
            result[-1]["values"].extend(item["values"])
            result[-1]["values"] = list(set(result[-1]["values"]))

            # Update the time window
            if end > parse_date(result[-1]["end"]):
                old_end = result[-1]["end"]
                result[-1]["end"] = item["end"]
                result[-1]["time_windows"].append({"start": old_end, "end": item["end"]})
        else:
            # Add a new item to the result
            result.append({"values": item["values"], "start": item["start"], "end": item["end"], "time_windows": [{"start": item["start"], "end": item["end"]}]})

    return result
Sign up to request clarification or add additional context in comments.

1 Comment

This is sort of what I've got at the moment, problem is it merges everything together as a whole.. rather than separting it out into time windows.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.