通过与设置的字母匹配的第一个字母排序列表

时间:2018-10-10 08:42:55

标签: c#

我有一个按排名排序的比赛清单。因此,排名为1的项目将比列表2更高。

在理论上,我也总是有一个匹配项,该匹配项应该与之紧密匹配,这就是排名所代表的含义。

例如,有时候我有多个项目的排名都为1。

我现在需要做的是继续按排名排序,然后再按Match的第一个字母(与SpokenWord变量匹配)进行排序。

因此,如果我有3个匹配项,并且有一个SpokenWord变量为“帐户”

Name: Dev, Rank: 1

Name: Finance, Rank: 1 

Name: Accounts, Rank: 1

我希望将“帐户”移到列表的顶部,因为它的首字母与实际所说的单词匹配。

.Net fiddle of the problem here

2 个答案:

答案 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;
}

请注意,这只是一个简单的实现,可能需要针对性能进行优化。

相关问题