匹配字符串集合

时间:2014-08-01 12:00:34

标签: c# .net string-comparison

我的List<Product>包含1000个产品,List<string>包含100个类别名称。

  • 班级Product包含NameDescriptionKeywords等属性。
  • Category列表的一个示例值为Bags, Luggage & Travel Accessories

我正在尝试使用Product的属性值匹配类别。

  • 我尝试过Levenshtein距离。
  • 我还尝试将类别拆分为单词并检查.Contains(keyword)

这样做的最佳方式是什么?

if (_subcategory.Name == "Others")
{
    var _items = _category.Items.Select(s => new
    {
        Item = s,
        Match = GetStringMatchingPercent(s.Name.ToLower().Split(_separators, StringSplitOptions.RemoveEmptyEntries).Where(w => w.Length >= 3).ToList(), new List<string>()
        {
            deal.description.ToLower(),
            deal.title.ToLower(),
            deal.keywords.ToLower()
        })
    }).OrderByDescending(s => s.Match).ToList();
}

private static double GetStringMatchingPercent(List<string> keywords, List<string> strings)
{
    int t = 0;
    int d = 0;

    try
    {
        foreach (string s in strings)
        {
            foreach (string k in keywords)
            {
                t++;

                if (s.Contains(k))
                {
                    d++;
                }
            }
        }

        return d / t * 100;
    }
    catch (Exception ex)
    {
        Utilities.HandleException(ex);
        return 0;
    }
}

2 个答案:

答案 0 :(得分:1)

如果我的问题是正确的;你可以使用以下代码:

List<string> categories = new List<string> {"Bags", "Luggage", "Travel", "Other"};

Product p = new Product();
p.Name = "MyProduct";
p.Keywords = "Luggage";
p.Description = "Some product";

Product p1 = new Product();
p1.Name = "MyProduct";
p1.Keywords = "Airport";
p1.Description = "Luggage";

Product p2 = new Product();
p2.Name = "MyProduct";
p2.Keywords = "Abc";
p2.Description = "Other";

List<Product> products = new List<Product> {p, p1, p2};

// Create a dictionary with a list of products for each category.
Dictionary<string, List<Product>> categorisedProducts = new Dictionary<string, List<Product>>();
foreach(string category in categories)
{
    categorisedProducts.Add(category, new List<Product>());
}

// Categorise the products.
categories.ForEach(category => products.ForEach(product =>
{
    string productString = product.Description + product.Keywords + product.Name;
    if (productString.Contains(category))
    {
        categorisedProducts[category].Add(product);
    }
}));

// Display all products with their category.
foreach (string s in categorisedProducts.Keys)
{
    foreach (Product prod in categorisedProducts[s])
    {
        Console.WriteLine("Name: " + prod.Name);
        Console.WriteLine("Description: " + prod.Description);
        Console.WriteLine("Keywords: " + prod.Keywords);
        Console.WriteLine("Category: " + s);
    }
}

Console.Read();

输出:

  

名称:MyProduct
产品描述:部分商品
关键词:行李箱分类:   行李号

名称:MyProduct
说明:行李箱关键词:机场   
类别:行李箱

名称:MyProduct
描述:其他
关键词:Abc   
类别:其他

它本质上做的是创建一个使用提供的类别作为键的Dictiory;因此,使用categorisedProducts["category"]可以获得该类别中的产品列表。

你必须首先填写它,当然。评论描述了发生的位置。对于categorylist中的每个字符串,它会搜索每个可用产品中提供的三个字符串。您可以根据自己的喜好添加产品的其他属性。

在bottem,它遍历所有产品并使用正确的类别显示其属性。

注意:如果产品中出现多个类别,则会将其添加到两者中。如果未找到类别,则跳过产品。 I have added "Other" as a category to make this work

答案 1 :(得分:1)

查看Jaro模式距离匹配的互联网。这应该指向正确的方向。我已经在不同的公司实现了这一点,如果正确完成了您正在寻找的并且非常快。

http://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance

干杯, 罗布