Searching for items in a JSON object using binary search

My JSON object contains data organized like this:

"time1": {
    "item1": "val1",
    "item2": "val2"
},
"time2": {
    "item1": "val3",
    "item2": "val4"
}
...

The time* values represent dates in milliseconds and are sorted in sequence.

Now, I need to search for an item based on the time key. If the key doesn't exist, I must find the nearest value. There are thousands of entries in the object and I'm considering using binary search, but I'm unsure about how to implement it.

The traditional method of calculating the middle position middle = (right+left)/2 cannot be used because the middle value might be undefined. Due to the fixed structure of my data, I am unable to utilize a binary tree.

Any insights or suggestions would be greatly appreciated.

Answer №1

If the median is undefined, a simple approach would be to take the middle key by dividing the length of the json by 2. Although not ideal, it gets the job done. Following this, a binary search can be conducted while keeping track of the index at each step. The goal is to check for indexes and determine whether to move left or right based on the value at each index. In case you reach a dead end and the searched time does not exist, you still have an idea of the surrounding values. For this, a final check using the formula if ((time_to_search - json[index-1]) > (json[index+1] - time_to_search)) can help decide which element is closer - index-1 or index+1. This operation is O(1) so there's no need to worry. You can then return either json[index-1] or json[index+1].

Does this explanation make sense to you?

I've also included a Fiddle for reference: http://jsfiddle.net/QFTJ5/

Please note that the Fiddle provided is not complete.

Answer №2

If you want to extract only the suffixes with a time label from an array, here's how:

let data = {
  "time1": {
    "item1": "value1",
    "item2": "value2"
  },
  "time2": {
    "item1": "value3",
    "item2": "value4"
  }
}
let postfixes = [];
for (let key in data) {
  postfixes.push(key.substring(4));
}

You can then perform a binary search on the extracted postfixes.

Answer №3

Given the scenario

var schedule = {
  "1367999303810": { 
    "task1": "value1",
    "task2": "value2"
  },
  "1368000000000": { 
    "task1": "value3",
    "task2": "value4"
  }
}

A potential coding solution could look like this (Math corrections needed!)

Live Example

function findClosestTime(targetTime) {
  for (var i=0; i<scheduledTimes.length; i++) {
    window.console && console.log(new Date(targetTime), new Date(scheduledTimes[i]))      
    if (targetTime === scheduledTimes[i]) return targetTime;  
    if (targetTime >= scheduledTimes[i]) break;
  }
  if (i == scheduledTimes.length) return -1; 
  if (i == scheduledTimes.length-1) return scheduledTimes[i];  
  var diff1 = Math.abs(targetTime - scheduledTimes[i]),     
  diff2 = Math.abs(scheduledTimes[i+1] - targetTime);   
   return diff1 === diff2 ? scheduledTimes[i+1] : 
          diff2 > diff1 ? scheduledTimes[i] : scheduledTimes[i+1]; 
}    

var scheduledTimes = [];

for (var t in schedule) scheduledTimes.push(parseInt(t));
scheduledTimes.sort();
var targetTime = new Date(2013,4,8,9,50,0).getTime(); 
var closestTime = findClosestTime(targetTime); 
if (closestTime != -1) window.console && console.log(schedule[closestTime])

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

What is the best way to retrieve the initial element from a map containing certain data?

I am attempting to retrieve the first image path directory from an API that contains an Image so I can assign the value to the Image source and display the initial image. However, when using fl[0], all values are returned. Below is the code snippet: {useL ...

Utilize a single JavaScript script to handle numerous HTML forms within the same webpage

I am currently facing an issue with a page that contains multiple forms needing the same JavaScript code. This specific code is designed to add more input fields to the form, which it does successfully. However, the problem lies in the fact that it adds in ...

While attempting to use JavaScript and AJAX to read a JSON object, I encountered an issue caused by the CORS

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Docu ...

When switching tabs in Javascript, the page does not automatically reload. However, the page will reload only when it is on

After writing a code using javascript/Youtube API + PHP to fetch a YT video ID from a MySQL server and place it in Javascript, I realized that the page only reloads when the tab is active and not when it's in the background. This issue disrupts the wh ...

Code malfunctioning

<html> <body> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> <script type="text/javascript> $('img').click(function(){ var ge ...

Display or conceal elements by utilizing ng-show/ng-hide according to specific conditions

Here is the code snippet I am working with: <input class="form-field form-control" type="text" name="Website" ng-model="vm.infodata.Website" placeholder="Website Address" maxlength="50" required ng-pattern="/^(www\.)?[a-zA-Z0-9_&bs ...

Utilizing Astro Project to gather content from various directories containing Markdown files

I am embarking on a project to convert Mark Down files (MD) into HTML format. While delving into this endeavor, I have chosen to utilize Astro due to its compatibility with MD to HTML conversion, even though I am relatively new to ASTRO or JSX style coding ...

"Is there a way to verify the existence of checkbox array values within a database using PHP Laravel

In order to display checkboxes for each country that exists in the database, I need to verify if the countries in the database match with those in the list. Since the values are retrieved directly from the database and can't be set as input values due ...

Access to Web Share API requires permission

I am currently attempting to integrate the Web Share API feature into my testing web application, but unfortunately, I seem to be encountering some difficulties. Below is the code snippet I have been working with: const newVariable: any = navigator; {newV ...

Exploring the Functionality of ngMousedown and ngMouseup in AngularJS

Is it viable to apply ngMousedown to add a class to a div, and then use ngMouseup to remove the class once more? Currently, I am utilizing ng-mousedown="activateClass()". Within the activateClass() function, I modify $scope.className="data-active", which i ...

Tips for showcasing chats with the most recent message highlighted

As I work on my web app using Laravel, I have encountered an issue where I need to scroll down to see the newest messages when there are many conversations. Here is how the chats display on page load I want to focus on displaying the newest message first. ...

Static file serving is malfunctioning

I created a basic node project to work on, but I'm struggling to serve an HTML file with its accompanying CSS styles. Previously, this exact code worked without any issues, but for some reason, it's not functioning now. I've tried searching ...

The error message in AuthenticatedLayout.jsx on line 43 indicates a problem with trying to access properties of an undefined object, specifically the 'name'

I am encountering this issue react-dom.development.js:26923 Uncaught TypeError: Cannot read properties of undefined (reading 'name') at AuthenticatedLayout (AuthenticatedLayout.jsx:39:55) AuthenticatedLayout.jsx import { useState } from "re ...

Items outside the container element

I recently noticed an issue with my website, which is built using Bootstrap. The problem arises when users scroll down the page and encounter the fixed navigation menu. It appears that the menu items and logo are no longer contained within the designated ...

Shifting v-slot references into a Vue.js component - tips and tricks!

I'm struggling to understand how to transfer the v-slot data into a component. Suppose I want to restructure the code below: <template v-slot:item="data"> <template v-if="typeof data.item !== 'object'"> <v-list-item-co ...

Instructions for transferring numerous chosen files (such as .doc, .pdf, .jpeg, .png) to a server from an Android device

Can you provide guidance on selecting multiple files from a file manager in Android? Once the details of the image are displayed (such as image size, name, and the option to delete the files), how can we upload these files to a server? ...

The order in which JavaScript is being executed is being reversed

function checkForDuplicate(center, email) { $.ajax({ type: "POST", url: "../staff/staffDA.php", data: "funId=-4&center=" + center + "&email=" + email, success: function (data) { if (data.split('| ...

Troubleshooting problem with populating data in Mongoose Database

Here is the code snippet: app.get("/cart", checkAuthentication, function (req, res) { Orders.find({ user: req.user._id }) .populate('user') .populate('order') .exec((err, orders) => { console.log(orders); ...

Unlimited scrolling with external JSON data in AngularJS

I am struggling with implementing an infinite scroll in angularjs using a JSON file from an external site. I want the infinite scroll to trigger when the posts variable reaches 10, then call my function, increment the URL by +1, and load a new page. Here i ...

The schema tag contains incorrect JSON syntax

Hey everyone, I'm completely new to Shopify and currently diving into the world of Liquid. I've encountered an issue with an invalid JSON tag in schema/ and I'm having trouble pinpointing its exact location. My goal is to create 4 basic bloc ...