Remove any overlapping datetime values from a JavaScript array of objects

Is there a way to efficiently remove any overlaps between the start and end times (moment.js) in a given array of objects?

[{ start: moment("2019-03-23T15:55:00.000"), end: moment("2019-03-23T16:55:00.000")},
 { start: moment("2019-03-23T14:40:00.000"), end: moment("2019-03-23T17:30:00.000")},
 { start: moment("2019-03-23T18:45:00.000"), end: moment("2019-03-23T19:45:00.000")},
 { start: moment("2019-03-23T17:10:00.000"), end: moment("2019-03-23T20:00:00.000")},
 { start: moment("2019-03-23T21:35:00.000"), end: moment("2019-03-23T22:35:00.000")},
 { start: moment("2019-03-23T19:15:00.000"), end: moment("2019-03-23T22:05:00.000")},
 { start: moment("2019-03-23T22:30:00.000"), end: moment("2019-03-23T23:30:00.000"),
}]

In the scenario above, all dates fall on the same day (03/23). To achieve the desired result, the algorithm should identify the earliest start time and the latest end time without any overlaps among the objects. The final array should consist of alternating start, end, start, end ... times.

For the provided example, the filtered result should be as follows:

start: 14:40:00
end:   17:30:00
start: 18:45:00
end:   20:00:00
start: 21:35:00
end:   23:30:00

In this output, start times are arranged chronologically, ensuring no overlaps between start and end times. All subsequent start times must occur after the previous end time.

Despite attempts to address overlapping issues, the current solution is ineffective. It still allows overlaps, highlighting the need for a more robust approach.

times.forEach(time => {
    // start with the first object
    if (filtered.length === 0) {
        filtered.push({'start': time.start, 'end': time.end});
    }
    // if this start time is AFTER the prior end time, add it
    if (time.start.isAfter(filtered[filtered.length-1]['end'])) {
        filtered.push({'start': time.start, 'end': time.end});
    }
    if (time.start.isBefore(filtered[filtered.length-1]['end'])) {
        // replace the prior end time
        filtered[filtered.length-1]['end'] = time.end;
    }
});

It is evident that the existing solution does not efficiently eliminate overlaps. Further exploration is needed to devise a more effective strategy.

Answer №1

boundaries = [];
times.forEach (time => {
  boundaries.push ({type: "start", value: time.start});
  boundaries.push ({type: "end", value: time.end})
});

This code snippet creates an array of boundaries with start and end values:

[
  {type: "start", value: moment("2019-03-23T15:55:00.000")},
  {type: "end", value: moment("2019-03-23T16:55:00.000")},
  {type: "start", value: moment("2019-03-23T14:40:00.000")},
  {type: "end", value: moment("2019-03-23T17:30:00.000")},
  {type: "start", value: moment("2019-03-23T18:45:00.000")},
  {type: "end", value: moment("2019-03-23T19:45:00.000")},
  {type: "start", value: moment("2019-03-23T17:10:00.000")},
  {type: "end", value: moment("2019-03-23T20:00:00.000")},
  {type: "start", value: moment("2019-03-23T21:35:00.000")},
  {type: "end", value: moment("2019-03-23T22:35:00.000")},
  {type: "start", value: moment("2019-03-23T19:15:00.000")},
  {type: "end", value: moment("2019-03-23T22:05:00.000")},
  {type: "start", value: moment("2019-03-23T22:30:00.000")},
  {type: "end", value: moment("2019-03-23T23:30:00.000")}
]

The next step is to sort the array by the value and then iterate over the sorted array. Count the number of "start" boundaries passed minus the number of "end" boundaries passed. Increase the counter on each "start" boundary and decrease it on each "end" boundary.

Whenever the counter transitions from zero to non-zero, output the filtered "start" boundary. Whenever the counter transitions from non-zero to zero, output the filtered "end" boundary.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Leveraging JavaScript and HTML to extract a single data point from a JSON response

As a complete beginner, I want to clarify that I may not be using the correct terminology in my question. I am embarking on creating an HTML5/Javascript application with Intel XDK to retrieve barcode information for video games from an online API. Specifi ...

Retain the chosen values even after submitting the form

Consider the following form: <form method="get" action=""> <select name="name"> <option value="a">a</option> <option value="b">b</option> </select> <select name="location"> <opt ...

Utilize node.js to run a local .php file within a polling loop

Here is the purpose of my application in brief. I am using a PHP file to read data via an ODBC connection and then write that data to a local database. This PHP file needs to be executed LOCALLY ON THE SERVER every time a loop is processed in my node.js, ...

What is the best way to handle this unconventional JSON structure?

Looking for some insight on retrieving process information from a VPS with PM2. However, the JSON string returned by PM2 is malformed, making it impossible to run JSON.parse(). An example of the output provided by PM2: '{data: 0, informations: " ...

Maximizing the power of datatables with ajax integration

Exploring pagination with AJAX on datatables.net is something I want to try. I have two input fields where users can enter start and end dates, followed by the table structure below: <table class="table table-hover" id="example"> < ...

Wordpress causing Jquery to malfunction; PHP function not executing

Looking to incorporate a script into my WordPress function.php file. Here's what I have so far: <?php function add_google_jquery() { if ( !is_admin() ) { wp_deregister_script('jquery'); wp_register_script('jquery', ...

The art of transforming properties into boolean values (in-depth)

I need to convert all types to either boolean or object type CastDeep<T, K = boolean> = { [P in keyof T]: K extends K[] ? K[] : T[P] extends ReadonlyArray<K> ? ReadonlyArray<CastDeep<K>> : CastDeep<T[P]> ...

JavaScript - Issue with retrieving object properties accurately

Here is a code snippet that I am working with: function retrieveObjects(name, data) { return data.filter(function(d) { return name.title == d.title; }).map(function(d) { return { "title": d.title, "sort": d. ...

Retry request with an AngularJS interceptor

Currently, I am in the process of developing an Angular application and encountering some challenges while implementing a retry mechanism for the latest request within an HTTP interceptor. The interceptor is primarily used for authentication validation on ...

Having trouble displaying image links with React Router

I have been working on designing a mock Instagram page, complete with icons for "Home", "Inbox", "Explore", "Notifications" & "Profile Icon" in the top menu bar. Initially, these icons were static and did not have any functionality, but they would displa ...

best way to eliminate empty strings from an array collection using javascript

I'm currently working on a search functionality where I separate each value in an array, and it's functioning properly. The issue arises when the user enters an empty value, causing the search to break as it returns an empty string within the arr ...

Refreshing information within a table using Ajax Prototype

For my current project, I am utilizing PrototypeJS. I have implemented Ajax.PeriodicalUpdater to insert real-time data as required. However, I am facing an issue where the data is not getting replaced inside a specific table. Below is the HTML code snippet ...

Divide an HTML file into separate documents upon submitting a form

Is there a way to input HTML into a text area, then upon submission, have the system read the file, identify the class selector, and separate the HTML into multiple files saved in a directory? If you have any thoughts on how this could be accomplished, pl ...

Incorporating Progressive Web App Support into a JavaServer Faces Web Application

Exploring the possibility of integrating Progressive Web App support into a JavaServerFaces web application has become a focal point for our team. As our JSF app continues to evolve, we foresee the need to provide offline access to certain parts of the app ...

Executing AJAX POST request with callback function

I successfully used this code for the get function to retrieve data. It works flawlessly and I am able to fetch the required data using this function. function getdata(getdatafrom, resultclass){ $.get(getdatafrom, function(data) { $(result ...

Updating an array and extracting a nested element from the array in a single operation

Looking at the following data: { "_id" : "123", "firstArray" : [ { "_id" : "456", "status" : "open", "nestedArray" : [ ...

Is it possible to close the menu by clicking outside a div or letting it disappear on mouseout after a set period of time?

When visiting a website, you may notice menus that display sub-menus when hovered over. These menus and sub-menus are created using div elements, with the sub-menus hidden initially using style.display = none; The issue arises when a sub-menu is opened an ...

Is it possible for Javascript to manipulate the DOM of an Ajax text/html response?

My goal is to implement Ajax to retrieve an HTML page and extract a specific div by its ID, then insert that div into the current page. This involves loading a second page via Ajax, extracting the specified div from the response, and placing it within th ...

The Javascript query is returning an [object Object] data type

I am facing an issue with a JavaScript file that is querying a SharePoint list. Specifically, the Priority drop down in the query result is displaying as [object OBJECT]. I suspect it has something to do with the var query string where I have added the &ap ...

What is the best approach to comprehensively organize a multidimensional list in Python while maintaining efficiency and cleanliness?

For instance: Given the following array elements: array = [[10, 9, 1], [2, 1, 1,], [4, 11, 16]] I want to transform it into: print array [[1, 1, 1], [2, 4, 9], [10, 11, 16]] Can I achieve this using the list.sort() function or would I need to c ...