我有一个按排名排序的比赛清单。因此,排名为1的项目将比列表2更高。
在理论上,我也总是有一个匹配项,该匹配项应该与之紧密匹配,这就是排名所代表的含义。
例如,有时候我有多个项目的排名都为1。
我现在需要做的是继续按排名排序,然后再按Match的第一个字母(与SpokenWord
变量匹配)进行排序。
因此,如果我有3个匹配项,并且有一个SpokenWord
变量为“帐户”
Name: Dev, Rank: 1
Name: Finance, Rank: 1
Name: Accounts, Rank: 1
我希望将“帐户”移到列表的顶部,因为它的首字母与实际所说的单词匹配。
答案 0 :(得分:1)
按Rank
排序,然后添加另一种排序,即如果首字母等于spokenWord
的首字母,则标记为0,否则为1。
matches.OrderBy(x => x.Rank).ThenBy(x=>x.Name[0] == spokenWord[0] ? 0 : 1)
因此,在相同排名中,所有匹配为0(第一个字母相等)的匹配都将排在首位,然后是其余
答案 1 :(得分:0)
其他答案给出了如何按顺序排列,后跟首个匹配字母,但是这不包括您的示例中搜索结果同时具有:帐户和应计费用的情况。然后,仅对第一个单词进行匹配,我们可能仍然会得出错误的排序顺序。
这为我们指明了方向,在该方向上,我们应根据搜索词与结果的子字符串匹配来尝试获得另一个排名。我认为这实际上应该在服务器端功能中完成,它可以为您提供Serach结果中的排名。
但是,简单的实现是:
static void Main(string[] args)
{
string spokenWord = "accounts";
HashSet<string> search = new HashSet<string>(); //tokenize the search keywords and store in dictionary...
for (int z = 0; z < 1; z++)
{
for (int inner = 1; inner <= spokenWord.Length - z; inner++)
{
// by default orders in order of increasing length of substring
search.Add(spokenWord.Substring(z, inner));
}
}
// for loop above wrtten usnig linq....however in this case I think for loops wins becuase of greater clarity
//var items = Enumerable.Range(0, 1).SelectMany(x => Enumerable.Range(1, spokenWord.Length - x).Select(j => spokenWord.Substring(x, j)));
List<Match> matches = new List<Match>();
matches.Add(new Match { Rank = 1, Name = "dev" });
matches.Add(new Match { Rank = 1, Name = "finance" });
matches.Add(new Match { Rank = 1, Name = "accounts" });
matches.Add(new Match { Rank = 1, Name = "abcounts" });
// ordering using rank and new searchrank score
foreach (var match in matches.Select(m => new { Name = m.Name, Rank = m.Rank, SearchRank = MatchRank(search, m.Name) }).OrderBy(x => x.Rank).ThenByDescending(x => x.SearchRank))
{
Console.WriteLine(String.Format("Name: {0}, Rank: {1}", match.Name, match.Rank));
}
}
MatchRank
函数为:
public static int MatchRank (HashSet<string> searchString, string value)
{
int result = 0;
foreach (var item in searchString.OrderByDescending(x=>x.Length))
{
if (value.StartsWith(item, StringComparison.Ordinal))
{
result = item.Length;
break;
}
result = 0; // no match
}
return result;
}
请注意,这只是一个简单的实现,可能需要针对性能进行优化。