Search code examples
javascriptarraysobjectbinary-search-tree

Can I do a binary search on an array of objects?


I am currently learning how to use searching and sorting algorithms and I am running into issues with a binary search on an array of objects of customers' data. The array of customers is sorted by first and last name.

The goal is to find a customer's email and return the index.

The data looks like:

[
  {
    "username": "Maude.Torp",
    "email": "Taya.Kerluke53@gmail.com",
    "address": {
      "street": "Rowe Fields",
      "suite": "Suite 231",
      "city": "Tiannamouth",
      "zipcode": "07584-6653",
      "geo": { "lat": "75.0283", "lng": "-17.1824" }
    },
    "phone": "795-827-5446 x18366",
    "website": "nico.com",
    "company": {
      "name": "Champlin, Feest and Barrows",
      "catchPhrase": "Object-based user-facing orchestration",
      "bs": "transition integrated content"
    },
    "firstName": "Maida",
    "lastName": "Feeney"
  },
  ...
]

My binary search function looks like:

function searchByEmail(email, customers) {
  let start = 0;
  let end = customers.length - 1;

  while (start <= end) {
    let middle = Math.floor((start + end) / 2);

    if (customers[middle] === email) {
      return middle;
    } else if (customers[middle] < email) {
      start = middle + 1;
    } else {
      end = middle - 1;
    }
  }
  return -1;
}

On a sorted array of numbers I am able to return the index of the desired key.

let customers = [1, 10, 45, 56, 66, 567]
...
console.log(searchByEmail(66, customers))

// --> 4

When I look through this array of objects I only return -1. How do I change this algorithm to work for objects within arrays?


Solution

  • You should be able to binary search the customer array, provided that it's ordered by customer email.

    Change the code up a bit to compare the email instead of the entire object, accessing the email property of the object.

    function searchByEmail(email, customers) {
      let start = 0;
      let end = customers.length - 1;
    
      while (start <= end) {
        let middle = Math.floor((start + end) / 2);
    
        // NOTE the ".email" part added
        if (customers[middle].email === email) {
          return middle;
        } else if (customers[middle].email < email) {
          start = middle + 1;
        } else {
          end = middle - 1;
        }
      }
      return -1;
    }