Skip to content

How to implement a ‘contains’ search in JavaScript

I’m creating a search box that allows you to search for different companies. I’d like the search box to perform a ‘contains’ search. For example, let’s say that I want to look up the company ExxonMobil Oil Corp. Typing in any of the following should include the company in the list of results (this isn’t exhaustive):

  • oil
  • corp
  • oil corp
  • exxonmobil
  • exxonmobil oil
  • exxonmobil oil corp

The words don’t have to be complete, just to be clear. The phrase ‘oil co’, for instance, should still bring up a result.

Typing in ‘exxonmobil corp’, however, will not bring up the company as a result since ‘corp’ does not immediately follow ‘exxonmobil’ in the company’s name.

Is there a go-to method for implementing this type of search, keeping time efficiency in mind? In my case, there can be thousands of companies to search through. And I’d like to be able to display the list of results on the fly as the user is typing into the search box.

I’m aware of the trie data structure, but from what I’ve read, it seems to work best for ‘starts with’ searches. So it wouldn’t match searches like ‘oil corp’, ‘oil’, or ‘corp’ with ExxonMobil Oil Corp. Perhaps there’s a way to tweak the trie to do as I want, but I’m just not sure if that’s the best way to go.

Thank you for the responses. A few of you suggested looking into String.prototype.includes(). I gave that a try, and it does seem to work well with no performance issues.

Answer

100 companies is fast.

const companies = [
  "Arcade Flower Shop",
  "Madam Malkin's Robes for All Occasions",
  "Victoria's Circuit",
  "33ยข Store",
  "El Banco Corrupto",
  "Silver Shamrock",
  "Stay Puft Corporation",
  "Wonka Industries",
  "Blue Moon Detective Agency",
  "The Foundation",
  "Macmillan Toys",
  "The Reef",
  "Merrick BioTech",
  "The Peach Pit",
  "The Korova Milkbar",
  "Paper Street Soap Company",
  "Mel's Diner",
  "Dunder Miflin",
  "The Everything Store",
  "Rodbell's",
  "Rex Kwan Do",
  "The Fairly Oddparents",
  "Vitameatavegamin",
  "Bushwood Country Club",
  "Consumer Recreation Services",
  "The Rusty Anchor",
  "IPS (International Parcel Services)",
  "Pendant Publishing",
  "Lacuna Inc.",
  "H.A.L. Labs",
  "Life Extension",
  "Rekall",
  "Bluehound Bus Line",
  "Atlantic American Airlines",
  "KACL",
  "Flingers",
  "Burrito Explosion",
  "Fatso's",
  "The Max",
  "McDowell's",
  "Bada Bing",
  "Wu-Tang Financial",
  "Wally World",
  "The Dharma Initiative",
  "The Leftorium",
  "Edna's Edibles",
  "Daily Planet",
  "21 Jump Street",
  "The Enterprise",
  "Powell Family",
  "Central Perk",
  "Night Court",
  "Arnold's Drive-In",
  "WKRP",
  "Moe's Tavern",
  "Lomax Industries",
  "Hudsucker Industries",
  "Los Pollos Hermanos",
  "Chubby's",
  "Mugatu Industries",
  "The Daily Bugle",
  "Globex Corporation",
  "Entertainment 720",
  "Soylent Corporation",
  "SS Minnow",
  "TGS with Tracy Jordan",
  "Grace Adler Designs",
  "Pierce & Pierce",
  "Wayne Enterprises",
  "Cheers",
  "Goliath National Bank",
  "Pricemart",
  "Career Transitions Corporation",
  "Bluth's Original Frozen Banana",
  "Livingston",
  "Luke's Diner",
  "Adventureland",
  "Buy-N-Large",
  "Average Joe's Gym",
  "Duff Beer",
  "Michael Scott Paper Company",
  "Brawndo",
  "Fisher & Sons",
  "Mitch and Murray",
  "Multi National United",
  "Oscorp",
  "Pizza Planet",
  "Momcorp",
  "Ewing Oil",
  "Prestige Worldwide",
  "Tyrell Corporation",
  "Omni Consumer Products",
  "Monsters Inc.",
  "Ghostbusters",
  "Pied Piper",
  "TelAmeriCorp",
  "Yakonomo Corporation",
  "Mega Lo Mart",
  "Vandelay Industries",
  "Frosty Palace",
  "Sterling Cooper Draper Pryce",
  "M.I.B.",
  "The Smash Club"
];


const search = document.getElementById("search");
const output = document.getElementById("output");

const filter = (evt) => {
  const val = evt.target.value;
  if (val.length < 1) return output.value = "";
  output.value = companies.filter(company => company.toLowerCase().includes(val.toLowerCase())).join("n");
}

search.addEventListener("keyup", filter);
input,
textarea {
  margin-top: 1em;
}
<link href="https://unpkg.com/marx-css/css/marx.min.css" rel="stylesheet" />
<main>
  <input type="text" id="search" />
  <textarea rows=4 id="output"></textarea>
</main>