What are some strategies for improving the speed of searching through an array of objects?

I've been exploring more efficient ways to search through an array of objects as my current approach is too slow. The array I'm working with has the following structure:

[
  {
    fname: 'r7942y9p',
    lname: 'gk0uxh',
    email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="95f4f3fce1acfaf2d5f2f8f4fcf9bbf6faf8">[email protected]</a>',
    phone: 2326571226
  },
  {
    fname: 'hipnr9f6',
    lname: 'rsnse5',
    email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef9d9699dbd89e86af88828e8683c18c8082">[email protected]</a>',
    phone: 7863302156
  },
...

I'm interested in searching the objects based on their email and phone properties and returning the first object that matches either the provided email or phone.

Question: Is there a more efficient alternative to

const log = data.find(item => {
    return (item.email && item.email === email) || (item.phone && item.phone === phone)
});

I've created a simple benchmark to analyze this scenario:

const data = [];
let r = len => Math.random().toString(36).substring(len);
let n = (min, max) => Math.round(Math.random() * (max - min));

for(let i = 0; i < 50000; i++){
    data.push(
        {
            fname: r(5),
            lname: r(7),
            email: `${r(6)}@gmail.com`,
            phone: n(10000000000, 20000000000)
        }
    )
}

const email = '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ee9d8a85828688828a8588ae89838f8782c08d8183">[email protected]</a>', phone = 19027931232;

console.time('search_time');
const log = data.find(item => {
    return (item.email && item.email === email) || (item.phone && item.phone === phone)
});
console.timeEnd('search_time')
console.log(log ? 'Found':'Not Found')

In the benchmark above, the data array is populated with 50,000 random elements and searched for email or phone matches. My node server reports an execution time of approximately 2.5 ms. This means that if I were to search the data array 10,000 times, which is a common scenario, I would have to wait for around 25 seconds. I'm looking for ways to optimize this process and make it faster.

It's important to note that the phone or email fields may not always be present in the data array, hence the need for checks like

(item.email && item.email === email)

Answer №1

If you're comfortable with preprocessing and utilizing a similar amount of memory as the data once more, you may want to consider creating a lookup object in advance (such as an index).

// Leveraging lodash library
const emailIndex = _.invertBy(data, 'email');
const phoneIndex = _.invertBy(data, 'phone');

It's worth noting that indexing is approximately 40 times slower than searching using your current method.

For reference, here is your benchmark code snippet:

const data = [];
let r = len => Math.random().toString(36).substring(len);
let n = (min, max) => Math.round(Math.random() * (max - min));

for (let i = 0; i < 50000; i++) {
    data.push(
        {
            fname: r(5),
            lname: r(7),
            email: `${r(6)}@gmail.com`,
            phone: n(10000000000, 20000000000)
        }
    )
}

const email = '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d2a1b6b9bebab4beb6b9b492b5bfb3bbbefcb1bdbf">[email protected]</a>', phone = 19027931232;

console.time('indexing_time');
const emailIndex = _.invertBy(data, 'email');
const phoneIndex = _.invertBy(data, 'phone');
console.timeEnd('indexing_time');

console.time('search_time');
const log = emailIndex[email] || phoneIndex[phone];
console.timeEnd('search_time');
console.log(log ? 'Found' : 'Not Found');
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cda1a2a9acbea58df9e3fcfae3fffd">[email protected]</a>/lodash.min.js"></script>

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

Struggling to get JavaScript to successfully load a .txt file in order to load various links

I created a cool feature that takes users to a random link, but I currently have a large list of links and wanted to find a way for JavaScript to read them from a text file. The code I have tried so far is not working, and I have experimented with other s ...

Issue encountered during creation of a polyline in Cesium

When attempting to create a polyline in my ReactJs app using the code below, I encountered an error message stating "DeveloperError: Expected value to be greater than or equal to 0.0125, the actual value was 0." Can someone shed some light on why this er ...

Exploring alternatives to ref() when not responsive to reassignments in the Composition API

Check out this easy carousel: <template> <div ref="wrapperRef" class="js-carousel container"> <div class="row"> <slot></slot> </div> <div class=&q ...

Utilizing a Frozen Tensorflow Model with NodeJS for High-Performance Computing

I am new to tensorflowjs and js in general, but I have a trained model that I need to run on it. I have converted the model to json format, but I am having trouble feeding data into it: const tf = require('@tensorflow/tfjs') const tfn = require( ...

Mapping a list of keys to Firebase objects in Vue.js

I am currently working on a compact web application using Vue.js and Firebase for data storage and synchronization. The app consists of storing 'items' with attributes like 'title' and 'subtitle', and 'lists' with an ...

Limiting the x-axis drag function in a grouped bar chart using D3.js

For those interested, here is the link to view the code snippet: http://jsfiddle.net/4tqn7162/1/. When dragging the bars left or right causing the width of svg plot to disappear, I am looking for a solution that can restrict this behavior without impacting ...

Using jQuery to smoothly scroll to a position determined by a custom variable

Here's the script I am working with: $('.how-we-do-it .items div').on('click', function () { var $matchingDIV = $('.how-we-do-it .sections .section .content div.' + $(this).attr('class')); $matchingDIV. ...

Is there a way to add additional text to a text element within an SVG?

Is it possible to append a new text element at the end of the data label by clicking on that particular text? I have attempted to implement this in my code but the additional text is not being displayed as expected: circleGroup.selectAll("text") ...

Error encountered while attempting to login to the Winston Logger in the /var/log directory

After hours of attempts, I am still struggling to get Winston to log in my /var/log directory on my Fedora system. I conducted a test project using Express and found that logging works fine within the project directory. However, when attempting to log any ...

"Troubleshooting issue: Popup in react-leaflet fails to display upon clicking

Currently, I have integrated react-leaflet into my ReactJS application to dynamically create markers with popups. However, when implementing the code as shown below, the popup box fails to display and an error message appears in the web developer console. ...

Guide on effectively managing props within a single component in React Navigation

When attempting to navigate from my App component to the GamePlay component, I encountered an issue. Here is a snippet of my App.js: import React from 'react'; import { StyleSheet, Text, View, TouchableOpacity } from 'react-native'; imp ...

Deciphering JSON strings using JavaScript

Here is a string that I am trying to parse using Json: {\"description\": \"PSY - Gangnam Style (\\uac15\\ub0a8\\uc2a4\\ud0c0\\uc77c) \\n\\u25b6 NOW available on iTunes: h ...

Conceal div elements and retain their status when the page is reloaded or switched

I currently have 3 div elements displayed on a webpage: header-div fixed_menu_div page_cont Each of these divs are styled with the following CSS properties: #header-div { top:0; left:0; display:inline; float:left; } #page_cont { mar ...

Obtaining HTML elements from JSON using jQuery (i.e., the opposite of serializing with Ajax)

I am looking to extract values from a set of controls (INPUT, SELECT, TEXTAREA) within a DIV and send them as JSON via Ajax to a server. Utilizing jQuery's serializeArray makes this process easy. After sending the JSON data, I expect the server to re ...

Waveform rendering in HTML5 using wavesurfer.js struggles to handle large mp3 files

Recently, I was considering incorporating wavesurfer.js into one of my projects so I decided to explore the demo on To test it out, I uploaded a large mp3 file (approximately 2 hours long) onto the designated area in the middle of the page. It appeared to ...

Execute index.js code from index.html using NodeJS and Express

Currently, I am diving into the world of NodeJS and Express using Replit.com for a small project. The main objective is to develop a basic input field that, upon submission, will post to different channels such as Discord and Twitter. The piece of code be ...

Validating a string with Hapi Joi validation for singles

Looking to perform basic validation on a single string, specifically the request header X-Value. Here's what I have tried. The issue I'm facing is that it always returns 'success' even when there is no X-Value header present. const ...

Number entered isn't visible in Bootstrap modal window

Can anyone help me troubleshoot why the value "APno" is not appearing next to "Appointment Number" in a Bootstrap modal despite the modal showing up? This is my code: Form <form method="POST> Appointment Number:<br> <input type="n ...

It is not possible to include external JavaScript in a Vue.js web page

Trying to integrate a Google Translate widget onto my webpage has been a bit challenging. Initially, when I added it to a normal webpage, it worked smoothly using the following code: <div class="google_translate" id="google_translate_element"></d ...

Troubleshooting VueJS route naming issues

I am having an issue with named routes in my Vue app. Strangely, the same setup is working perfectly fine in another Vue project. When I click on a named router-link, the section just disappears. Upon inspecting the element in the browser, I noticed there ...