Search code examples
algorithmflutterdartsearchranking

rank items in list of string in dart


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?


Solution

  • 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