Home > OS >  OrderBy search results that startswith searcch word then by results that contains search word
OrderBy search results that startswith searcch word then by results that contains search word

Time:11-08

I have an object like this:

  public class MyObject
{
    public List<string> Names { get; set; }
    // other props
} 

and I have a filtered List like this :

   var freeText = "comm";
    var list = new List<MyObject>(); // Initialized

    var searchResult = list.Where(o =>
        o.Names.Any(n => n.ToLower().StartsWith(freeText.ToLower())) ||
        o.Names.Any(n => n.ToLower().Contains(freeText.ToLower())));

and it's working fine but, what I'm trying to do is to get the search results ordered by starts with first then by contains.

ex:

Obj 1 {Names : [ "free communication" ,"some name"]},
Obj 2 { Names : ["communcation Center", "whatever"]}

I want the result to be [Obj2, Obj1].

I tried to orderBy index of freeText but it doesn't seem to work on an array/list of string. I tried to ulter the solution at This question so it works on array instead of string but it didn't work. any idea how to to this?

CodePudding user response:

You can implement a simple scoring mechanism where you'll capture two flags (startsWith and contains) and use those flags both for filtering and for sorting:

var result = list.Select(item => new
{
    item,
    startsWith = item.Names.Any(n => n.ToLower().StartsWith(freeText.ToLower())),
    contains = item.Names.Any(n => n.ToLower().Contains(freeText.ToLower())),
})
.Where(item => item.startsWith || item.contains)
.OrderByDescending(item => item.startsWith)
.ThenByDescending(item => item.contains)
.Select(x => x.item);
  • Related