Closest Linq search result

I have an ObservableCollection that contains a Person object. I have a search function in my application and you want to display the most relevant results at the top. What would be the most efficient way to do this? My current search method simply calls the contains method:

  var results = (from s in userList where s.Name.Contains(query) select s).ToList(); 

This works fine, but the results are ordered in the same order as in userList . If I search for Pete , then it must first display Pete , then Peter , then Peter Smith , etc. It should not be too complicated, as it will only deal with a few thousand (maximum) results. My naive approach was to do s.Name == query , display that element (if any), then do s.Name.Contains(query) , delete the matched element and add it to the previous matched result. However, this seems a bit everywhere, and is there a better way? thanks (ps - only the name will be used in the search, and I can not use SQL methods)

+6
c # search linq windows-phone-7 observablecollection
source share
3 answers

You can create a single routine that provides a name and a query string, and returns an integer value.

Once you do this, just go back in order:

 int QueryOrder(string query, string name) { if (name == query) return -1; if (name.Contains(query)) return 0; return 1; } 

Then do:

 var results = userList.OrderBy(s => QueryOrder(query, s.Name)); 

The best part about this approach is that you could later expand the procedure to provide more detailed information that allows you to sort by the “good” match you get. For example, “Pete” → “Peter” is probably better than “Pete” → “Peter Smith,” so you could get your logic back for different options ...

If you need to remove non-Pete matches, you can also exclude the Where clause.

+10
source share

You need some kind of scoring function for similarities. Then you can simply do:

 from s in userList let score = Score(s, query) where score > 80 orderby score descending select s; 

(Suppose the scoring function gives a value from 0 to 100, where 100 is a perfect match.)

Now it’s not clear from your example what the scoring function should be - what should be worked out for you :)

+7
source share
 var results = (from s in userList where s.Name.Contains(query) orderBy s.Length select s).ToList(); 
0
source share

All Articles