rank items in list of string in dart

273

You need to modify your method as

Future<List<String>> getSuggestions(String search) async {
  List<String> result = [];
  recipeNamesList.forEach((word){
    
    int value = getMatching(search,word);
    if(value > 0){
      if(result.isNotEmpty){
        if(getMatching(search,result[0]) > value){
          //only insert the maximum matched value at starting. it is some type of sorting
          result.add(word);
        }else{
          result.insert(0,word);
        }
      }else{
        result.add(word);
      }
    }
  });
}

A basic function to count the exact matched words

int getMatching(String input, String word){
   List<String> inn = input.split(' ');
   List<String> words = word.split(' ');
   int temp = 0;
   inn.forEach((inWord){
     if(words.contains(inWord)){
       temp++;
     }
   });
   
   return temp;
 }

Output with the input getSuggestions('Bengali Lamb Fries')

enter image description here

Share:
273
Daniel Bellmas
Author by

Daniel Bellmas

Updated on December 30, 2022

Comments

  • Daniel Bellmas
    Daniel Bellmas over 1 year

    Let's consider a list:

    List<String> recipeNamesList = [
      'Burger',
      'French Fries',
      'Pizza',
      'Bengali Lamb Curry',
      'Chingri Malai Curry',
    ]
    

    If the user searches Bengali Lamb Fries I need to return Bengali lamb curry and French Fries.

    Benagli Lamb Curry will have the highest rank since it has 2 words matching and French Fries has only one word that matches.

    So the returned list will be something like this:

    List<String> result = [
      'Bengali Lamb Curry',
      'French Fries'
    ]
    

    My current code:

      Future<List<String>> getSuggestions(String search) async {
        List<String> results = [];
        List<String> searchSplit =
            search.toLowerCase().split(" "); // split the search query
    
        for (int i = 0; i < searchSplit.length; i++) {
          // iterate over search query
          for (int j = 0; j < recipeNamesList.length; j++) {
            // iterate over the recipe names list
            List<String> recipeNamesListSplit =
                recipeNamesList[j].split(" "); // split the recipe names
            for (int k = 0; k < recipeNamesListSplit.length; k++) {
              // iterate over the list of splitted name
              if (recipeNamesListSplit[k]
                  .toLowerCase()
                  .startsWith(searchSplit[i])) {
                // convert to lower case and check if the query is present in splitted name
                results
                    .add(recipeNamesList[j]); // if contains == true add to results
              }
            }
          }
        }
    
        // Avoid repeated values
        results = results.toSet().toList();
        return results;
      }
    

    It's a completely ad-hoc that only matches if the query word is present in the recipeNamesList. And if so adds them to the results list. It does not rank which recipe has the most matched words from the search query.

    How am I supposed to rank? Is it possible with my current code with modifications? Or do I need to completely change my code?