在列表中查找部分关键字/关键字

时间:2014-03-27 08:10:39

标签: c#

我正试图找到一种从列表中查找单个单词或多个单词的方法。用户输入单词,并根据名称从ItemList中提取有关该项目的信息。

例如:

PriceList[0].name="Black Sheep"
PriceList[1].name="Black Horse"
PriceList[2].name="White Horse"
PriceList[3].name="White Sheep"

是列表中的一些项目,其中PriceList是ItemList,如下所示:

public class ItemList
{
public int amount { get; set; }
public string name { get; set; }
public int buyprice { get; set; }
public int sellprice { get; set; }
public int stock { get; set; }
}

这就是我想要的代码:

  • 案例1:用户要求" Black" :返回索引0,1。
  • 案例2:用户要求" White" :返回2,3。
  • 案例3:用户要求"马" :返回1,2。
  • 案例4:用户要求"绵羊" :返回0,3。
  • 案例5:用户要求" Black Horse" :返回1.
  • 案例6:用户要求"白马" :返回2.
  • 案例7:用户要求" Whit Horse" :返回2但不是1。
  • 案例8:用户要求" Red Horse" :返回1,2。

我目前有:

int nickindex = PriceList.FindIndex(x => x.name.Split().Contains(typeToAdd));

其中typeToAdd是用户输入字符串。

但是,这仅返回一个索引,并且对于案例5及更高版本失败。

如何循环遍历所有索引才能找到它们?我还需要能够搜索短语而不是单词。最后,如果找不到匹配项,我需要在单词内搜索(案例7)

我看过Algorithm to find keywords and keyphrases in a string,但它对我没什么帮助。

任何帮助将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:3)

您可以使用Select的重载来为您提供初始化匿名类型的索引:

string[] words = "Black Horse".Split();
IEnumerable<int> indices = PriceList
    .Select((pl, index) => new { pl, index })
    .Where(x => words.Intersect(x.pl.name.Split()).Any())
    .Select(x => x.index);

我正在使用Enumerable.Intersect检查输入字符串中的一个单词是否与名称中的某个单词匹配。

如果您想按照匹配次数进行降序排序:

IEnumerable<int> indices = PriceList
    .Select((pl, index) => new 
    { 
        pl, 
        index, 
        matches = words.Intersect(pl.name.Split()).Count()
    })
    .Where(x => x.matches > 0)
    .OrderByDescending(x => x.matches)
    .Select(x => x.index);

然而,这并未涵盖您的最后案例,因为它不会比较单词的相似性。你可以使用Levenshtein算法。你的规则在6-8也不是那么清楚。