Home > Enterprise >  Search an Array by all the properties
Search an Array by all the properties

Time:01-15

Users are allowed to search their data by keying Name or City or Code. How can I display matched object on the top of the dropdown list.

Prioritizing Code here as when user enters JOH the following obj will be highlighted.

{
  name: 'John Cena',
  code: 'JOH',
  city: 'California'
}

Below code works only if user enters the full name or code or city. The list has over 1000 records.

Trying to match the 3 characters code first with that of user input or otherwise by name or city.

let userInput = e.currentTarget.value;
const input = userInput.toLowerCase()
const filtered = []
if(userList){
  for (const user of userList) {
    if (user.code.toLowerCase().indexOf(input) > -1
        || user.city.toLowerCase().indexOf(input) > -1 
        || user.name.toLowerCase().indexOf(input) > -1
        ) {
          filtered.push(station)
        }
    
  }
}

CodePudding user response:

If you also need some sort of priorization (ie a match in code counts more than a match in name) you will need to weigh each match and then sort by weight. Assuming userList is an array

let results = userList.map(user => {
     let weight = 0;
     if (user.code.toLowerCase().includes(input)) weight = 900
     else if (user.name.toLowerCase().includes(input)) weight = 800
     else if (user.city.toLowerCase().includes(input)) weight = 700

     return { user, weight };
   })
   .filter(x => x.weight > 0)
   .sort((a,b) => b.weight - a.weight)
   .map(x => x.user);

This will return a list of users sorted by the best match (ie match by code) first. It's not super efficent, as it's traversing the list multiple times, but actually I don't think this will be a real issue at just 1000 elements ...

If you run into performance issues, you could for instance refactor userlist.map(...).filter(...) into userlist.reduce() but I leave that up to you ... For understanding the solution, I think map and filter are easier to read.

  • Related