Sort array in Javascript (Example)

Viewed 86

I have some data in the database used for a SEARCH BAR. In this table the field is called searchPeople (all lowercase) and contains data like:

 Name##CityName
 john##rome
 romeu##napoli
 romeu2##milan

So the user types on the SEARCH BAR some thing Rome, people that contain Rome in either their name or city. The search works well but I would like to "PRIORITIZE" the exact match String on top of the array. currently the data comes in random by the database order

 {
    name: 'John',
    city: 'Rome'
  }

Should be on top because the city matches === the string given by the user. THis can either be the name or city, I just gave an example using city match

const people = [{
    name: 'Romeu',
    city: 'Napoli'
  },
   {
    name: 'John',
    city: 'Rome' // this object should be first because there is a matching result
  },
  {
    name: 'Romeu2',
    city: 'Milan'
  }
];

console.log(people);

   // How can I sort people array with most relevant results on top?

Is there a way to sort my array to put the more correct search results on top?

4 Answers
people.sort((a, b) => {
if(a.city.toLowerCase() === '*user-input*'.toLowerCase() || a.name.toLowerCase() === '*user-input*'.toLowerCase()) {
  return -1;
}
return 0;
})

you can try this.

You can do it like this:

  • sort - to sort original array
  • includes - to check if user input is exact match of either name or city property.

const data = [
  { name: 'Romeu', city: 'Napoli' },
  { name: 'John',  city: 'Rome' },
  { name: 'Romeu2', city: 'Milan' },
];

const result = data.sort((a, b) => [a.name, a.city].includes('Rome') ? -1 : 0);
console.log('Result: ', result);

What you're speaking about is called 'relevance'. And you need somehow calculate it. And first you need to define it somehow. What is considered as more relevant in this particular search? Is name match more relevant than city match? Strict match is more relevant than partial match, that's clear.

So, strict match contributes to relevance value more that a partial match. For instance, strict match on field 'city' might give a value of 10 to a relevance score. While partial match on the beginning of a name can give value of 5. And maybe some variations of partial match contribute more than others.

For instance, search term me might contribute 1 for name Romeu and contribute 2 for city Rome (because matching the end might be defined as a more relevant than matching some center part of the word). And so on.

Does this do what you want?

Function reorder accepts the array to sort, the field to sort on, and the query string. It constructs a regular expression that looks for the exact word, delineated by word boundaries; this is then used to sort the array on the basis of matches.

If you want to sort on a second field (eg 'name'), then you could run this function again on that field.

const people = [{
    name: 'Romeu',
    city: 'Napoli'
  }, {
    name: 'John',
    city: 'Rome'
  }, {
    name: 'Romeu2',
    city: 'Milan'
  }]

const reorder = ({ arr, field, q }) => {
    let r = new RegExp(`\\b${q}\\b`, 'u')
    
    return arr.sort(({ [field]: aField }, { [field]: bField }) => {
        if(r.test(aField) && !r.test(bField)) return -1
        if(!r.test(aField) && r.test(bField)) return 1
        return 0
    })
}

console.log(reorder({ arr: people, field: 'city', q: 'Rome' }))

Related