Home > Back-end >  How to sort the data from the array in the order as they appear for the exact match?
How to sort the data from the array in the order as they appear for the exact match?

Time:07-18

I need to filter the data based on first matching character or string of that word and print the result as below.

  1. Input: 'T' or 'Th' or 'The' Output: ['The Shawshank Redemption', 'The Godfather', 'The Godfather: Part II', 'The Dark Knight', 'Dora the explorer']

  2. Input: 'Da' Output:['Dark Knight', 'The Dark Knight']

In the first case, 'T/Th/The' is the exact match for ('The Shawshank Redemption', 'The Godfather', 'The Godfather: Part II', 'The Dark Knight'). Yes, Dora the explorer is also a valid one as 'T/Th/The' is part of the string, but I need to push it to the last.

The logic what I wrote returns ["Dora the explorer", "The Shawshank Redemption", "The Godfather", "The Godfather: Part II", "The Dark Knight"] which is not correct. Same applies for the second one too. I'm not sure what did I do wrong here.

const fruits = ['Dora the explorer', 'The Shawshank Redemption', 'The Godfather', 'The Godfather: Part II', 'The Dark Knight', 'Dark Knight'];

const character = "The";

const filteredNames = fruits.filter((item) => {
  const subStrLength = character.length;
  return item.split(' ').some(el => el.slice(0, subStrLength).toLowerCase() === character.toLowerCase())
}).sort((a, b) => a.toLowerCase().indexOf(character) - b.toLowerCase().indexOf(character))

console.log(filteredNames)

CodePudding user response:

Here's one approach. While sorting we check if both the movies to sort are starting with the character and store them in isGoodMatchA and isGoodMatchB, if one of them is false and the other true, then we give priority to the true one. Else if both of them are true or if both of them are false, we do a simple localeCompare to find which comes first.

const fruits = ['Dora the explorer', 'The Shawshank Redemption', 'The Godfather', 'The Godfather: Part II', 'The Dark Knight', 'Dark Knight'];

const character = "The";

const filteredNames = fruits
 .filter((item) => item.toLowerCase().includes(character.toLowerCase()))
 .sort((a, b) => {
    const key = character.toLowerCase();
    const isGoodMatchA = a.toLowerCase().startsWith(key);
    const isGoodMatchB = b.toLowerCase().startsWith(key);

    if (isGoodMatchA ^ isGoodMatchB) { // XOR
        return isGoodMatchA ? -1 : 1;
    }

    return a.localeCompare(b);
});

console.log(filteredNames)

Array.prototype.includes()

String.prototype.startsWith()

  • Related