Best JavaScript approach for discovering time-dependent occurrences

In my Javascript code, I am working with an array of objects that have event start and end times stored as milliseconds. The current search algorithm in our codebase loops through the array until finding an event that contains a specific moment:

// Looking for an event based on a specific time

profile.tempbasaltreatments.forEach( function eachTreatment (t) {
    if (time <= t.endmills && time >= t.mills) {
      return t;
    }
});

However, this approach is not efficient when dealing with larger datasets. What would be a more suitable algorithm or data model to search through the object array effectively and find an event that includes a specified moment in time? It can be assumed that if events overlap, the first matching event encountered is sufficient.

Answer №1

Before searching, I recommend implementing the following pre-processing steps:

  1. If necessary, make a copy of the original array for future reference;
  2. Arrange the array based on event start times. Ideally, this should be handled by the database with an index specifically for this purpose;
  3. Eliminate events from the array that end before the previous event's end time. Since a matching event is sufficient, any overlap can be disregarded.

Subsequently, conduct a binary search as outlined below:

  1. Define the search range as the entirety of the array, represented by start and end indices;
  2. Select the middle element within that range;
  3. If this event aligns with the specified time, conclude successfully;
  4. If the start time of this event exceeds the given time, repeat from step 2 with the latter half of the range;
  5. Otherwise, proceed with the first half of the range (prior to the selected element) and return to step 2;
  6. Termination occurs when there are no more events in the range, resulting in failure.

The pre-processing stage only needs to be executed once, with a time complexity of O(n log n) if sorting is required; otherwise, it simplifies to O(n). Subsequent event searches can then be accomplished in O(log n) time.

Below is a snippet of JavaScript code encompassing the aforementioned process:

// Make a sorted copy of the original event array
var events = profile.tempbasaltreatments.slice(0).sort(function (a, b) { 
    return a.mills - b.mills;
});

// Remove redundant events to streamline the search process
for (var i = 0; i < events.length-1;) {
    if (i && events[i].endmills < events[i-1].endmills) {
         events.splice(i, 1);
    } else {
         i++;
    };
}
// The remaining events are also sorted by their end dates

// Function for efficiently locating events in the array:    
function findEvent(events, time) {
    // Binary search for event
    var first = 0, last = events.length - 1;
    while (first <= last) { 
        var i = first + Math.floor((last - first) / 2);
        var t = events[i];
        if (time >= t.mills && time <= t.endmills) return t;
        if (time < t.mills) {
            last = i - 1;
        } else { // time > t.endmills
            first = i + 1;
        }
    }
    // Undefined is returned if no match is found
}

// Example usage: locate a currently ongoing event
var matchedEvent = findEvent(events, new Date().getTime());

Additional Information

This section elucidates the filtering process in the final pre-processing step. Initially, events are organized according to their start times:

a: ---------------
b:     -------
c:      ------------------
d:         --
e:            --  
f:                -----

The events subject to elimination are identified sequentially, starting with b:

a: ---------------
c:      ------------------
d:         --
e:            --  
f:                -----

Then, d gets removed:

a: ---------------
c:      ------------------
e:            --  
f:                -----

Following that, e is excluded:

a: ---------------
c:      ------------------
f:                -----

Last to be removed is f:

a: ---------------
c:      ------------------

Evidently, the overall coverage period remains unchanged compared to the original arrangement before filtering.

Answer №2

If the events are organized by their start, mid, or end times, a binary search can be utilized to find a nearby event. Subsequently, a local linear search can be conducted to locate an event that includes the desired time stamp. The direction of the local search depends on the sorting order; for instance, if sorted by start time, the search should proceed towards decreasing start times from the closest event.

However, one drawback of this method is its inefficiency when there is no maximum event duration. In such cases, the local search lacks a definitive stopping point other than reaching the end of the list.

An alternative and more efficient solution may involve storing the events in a data structure optimized for quick access, such as an interval tree.

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

How can I adjust the animation speed for ChartJS graphics?

Trying to adjust the animation speed of a pie chart in chartJS. Various methods have been attempted: numSteps: Number animationSteps: Number Chart.defaults.global.animationSteps = Number However, none of these approaches have successfully altere ...

Is there an XML File Wrapper to Generate PDF Output?

Greetings Forum Members, I have been given the responsibility of creating a PDF file from multiple XML files. Has anyone come across an XML wrapper file before? This type of file would essentially contain a list of all the source XML file names in a spec ...

What is the best way to display data from the Nuxt.js store?

I am new to Nuxt JS and following a tutorial on the Nuxt website. I created a store in store/index.js. export const state = () => ({ mountain: [], }) export const mutations = { addMountain(state, mountain) { state.mountain.push(mountain) }, } ...

Transform a string into a property of a JSON object

One of my challenges involves extracting a value from a JSON object called Task, which contains various properties. Along with this, I have a string assigned to var customId = Custom_x005f_f3e0e66125c74ee785e8ec6965446416". My goal is to retrieve the value ...

What strategies can be utilized to condense code when needing to adjust a className based on various props?

I am looking to condense this code, particularly the [if~else if] block, in order to dynamically change a className based on different props passed. export default function Button(props) { const { name, height, color, bgColor } = props; let className = ...

Updating values within an ng-repeat loop by using the ng-change directive to increment or decrement

Below is an example code snippet that demonstrates a checkbox feature: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Welcome to LearnKode - A code learning platform</title> ...

Routing static pages in Angular 2

I successfully created a static page using Angular 2. When I run ng serve and visit my page, it functions as intended. Specifically, I can navigate to a specific page by typing in the URL, such as www.mysite.com/resume. However, after uploading it to my si ...

How can parameters be passed to a JavaScript or jQuery function?

I am currently utilizing a JS/JQ function to convert values into currency by adding commas. Although the function is running smoothly, I am encountering an issue when attempting to pass parameters to it. Kindly provide assistance on how to successfully pas ...

issues arise when using array_merge, serialize, and unserialize functions in PHP

I am faced with the following task: Insert an associative array into a database field so that it can be reused as an associative array. [Completed using serialize($associativeArray)] Retrieve the associative array from the database and view it as an arra ...

An express error caught off guard: Unexpected "write after end" issue detected

My current goal is to create a proxy for an api call from the client side through my server for a third party service. The main reasons for implementing this proxy are due to CORS issues and the need to include a secret key on the server side for added sec ...

Unexpected behavior in AJAX call

I'm currently working on implementing an AJAX call to display a partial view once a radio button is selected. Despite following the recommendations found on Stack Overflow comments, I am encountering difficulties. Upon selecting the radio button, ther ...

Tips for resetting the mapbox geocoder

Using the Mapbox Geocoder along with multiple select menus to customize a map has been my latest project. I am currently working on resetting the geocoder once a user selects an option from the menu, clearing the input field and removing the marker in the ...

Enhancing the appearance of individual cells in jQuery DataTables

While working with jQuery DataTables, I have successfully managed to access row data and apply styling to the entire row. Below is the code snippet used to initialize the datatable: var $dataTable = $('#example1').DataTable({ "data": data, ...

Loop through each instance of a data record in a JSON document using Vue's v-for directive

I am currently working on a project that involves extracting data from a website that monitors traffic jams and maintenance work. My goal is to specifically retrieve information about traffic jams and display them individually. The code I am using utilize ...

Tips on Extracting Data from a JSON Object with an Embedded Array

Check out this example of a Json Object: {"UserName":Mike,"IsActive":0,"ChbxIsActive":false,"MyAccountsAvailable":[{"Id":"157A","MyAccount":"CHRIS MCEL","MyCheckBox":false,"Tags":null},{"Id":"157B","MyAccount":"DAN BONE","MyCheckBox":false,"Tags":null} He ...

Leveraging php arrays for database interrogation

I am attempting to query a MySQL database using values passed in an array. The issue I'm facing is that the first element produces two results instead of one. Below is the code snippet and the corresponding results. $common = array_intersect($ingredi ...

Issues arising while passing a parameter to a Node.js module

I've been struggling with passing a variable to a module. In my node.js setup, I have the following structure: The main node.js server (server.js): // modules ================================================= var express = require('expr ...

Is there a way to retrieve the value of an element by clicking on its corresponding button using MUI framework?

I am working on a dashboard feature where I need to update the status by clicking on it. However, I am facing an issue with changing the state value upon clicking. Here is my component: <MenuItem> <Button fullWidt ...

Deletion of a custom function in JavaScript

I have written some basic code to generate and remove an image using functions. Specifically, I need help with removing the image created by the function Generate() when a button linked to the function Reset1() is clicked. Here's the code snippet for ...

How can I achieve a fade-in effect whenever the flag image is clicked?

A unique "international" quotes script has been created, showcasing Dutch, English, German, and French quotes. The script displays different quotes every day, with a draft-result visible in the upper right corner of this page ... The code used for this sc ...