I am trying to write a custom comparer to sort a list of search results based on similarity. I would like the term most like the entered search term to appear first in the list, followed by phrases that start with the search phrase, then all other values in alpha order.
Given this test code:
string searchTerm = "fleas";
List<string> list = new List<string>
{
"cat fleas",
"dog fleas",
"advantage fleas",
"my cat has fleas",
"fleas",
"fleas on my cat"
};
I'm trying to use this Comparer:
public class MatchComparer : IComparer<string>
{
private readonly string _searchTerm;
public MatchComparer(string searchTerm)
{
_searchTerm = searchTerm;
}
public int Compare(string x, string y)
{
if (x.Equals(_searchTerm) |开发者_如何学JAVA|
y.Equals(_searchTerm))
return 0;
if (x.StartsWith(_searchTerm) ||
y.StartsWith(_searchTerm))
return 0;
if (x.Contains(_searchTerm))
return 1;
if (y.Contains(_searchTerm))
return 1;
return x.CompareTo(y);
}
Calling list.Sort(new MatchComparer(searchTerm) results in 'my cat has fleas' at the top of the list.
I think I must be doing something odd/weird here .. Is something wrong here or is there a better approach to what I'm trying to do?
Thanks!
You aren't using the all of the possible return values for CompareTo
-1 == x first 0 == are equal 1 == y first
you want something more like this
public class MatchComparer : IComparer<string>
{
private readonly string _searchTerm;
public MatchComparer(string searchTerm)
{
_searchTerm = searchTerm;
}
public int Compare(string x, string y)
{
if (x.Equals(y)) return 0; // Both entries are equal;
if (x.Equals(_searchTerm)) return -1; // first string is search term so must come first
if (y.Equals(_searchTerm)) return 1; // second string is search term so must come first
if (x.StartsWith(_searchTerm)) {
// first string starts with search term
// if second string also starts with search term sort alphabetically else first string first
return (y.StartsWith(_searchTerm)) ? x.CompareTo(y) : -1;
};
if (y.StartsWith(_searchTerm)) return 1; // second string starts with search term so comes first
if (x.Contains(_searchTerm)) {
// first string contains search term
// if second string also contains the search term sort alphabetically else first string first
return (y.Contains(_searchTerm)) ? x.CompareTo(y) : -1;
}
if (y.Contains(_searchTerm)) return 1; // second string contains search term so comes first
return x.CompareTo(y); // fall back on alphabetic
}
}
精彩评论