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);