从列表2中筛选列表1

时间:2016-12-22 14:53:07

标签: c# linq list filter

我在这里遇到了性能方面的问题。

我到List包含(50k项) 和列表包含(120k项目)

WholeSaleEntry是

public class WholeSaleEntry
{
    public string SKU { get; set; }
    public string Stock { get; set; }
    public string Price { get; set; }
    public string EAN { get; set; }
}

和ProductList

public class ProductList
{
    public string SKU { get; set; }
    public string Price { get; set; }
    public string FinalPrice { get; set; }
    public string AlternateID { get; set; }

}

我需要通过其EAN及其SKU过滤WholeSaleEntry,以防它们的EAN或SKU位于ProductList.AlternateID中 我写了这段代码,但是性能很慢

       List<WholeSaleEntry> filterWholeSale(List<WholeSaleEntry> wholeSaleEntry, List<ProductList> productList)
    {
        List<WholeSaleEntry> list = new List<WholeSaleEntry>();
        foreach (WholeSaleEntry item in wholeSaleEntry)
        {
            try
            {
                string productSku = item.SKU;
                string productEan = item.EAN;
                var filteredCollection = productList.Where(itemx => (itemx.AlternateID == productEan) || (itemx.AlternateID == productSku)).ToList();

                if (filteredCollection.Count > 0)
                {
                    list.Add(item);
                }
            }
            catch (Exception)
            {
            }
        }

        return list;
    }

是否有更好的过滤系统或可以批量过滤的东西?

2 个答案:

答案 0 :(得分:6)

.Where(...).ToList()的使用将找到每个匹配的项目,最后您只需要知道是否有匹配的项目。这可以使用Any(...)来修复,var hasAny = productList.Any(itemx => itemx.AlternateID == productEan || itemx.AlternateID == productSku); if (hasAny) { list.Add(item); } 会在找到匹配后立即停止,如下所示:

HashSet


更新:算法可以简化为此。首先使用var uniqueAlternateIDs = new HashSet<string>(productList.Select(w => w.AlternateID)); var list = wholeSaleEntry .Where(w => uniqueAlternateIDs.Contains(w.SKU) || uniqueAlternateIDs.Contains(w.EAN)) .ToList(); return list; 获取唯一的备用ID,该HashSet<string>仅存储一次重复项,并且对于查找而言是快速疯狂的。然后获取与之匹配的所有WholeSale项目 没有更快的策略,代码很小,我觉得很容易理解。

List<string>

快速测试显示,对于50k + 50k项目,使用.Distinct().ToList()需要28ms才能得到答案。使用$config['base_url'] = 'http://www.xxxxxxx.com/'; 填充RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L] 需要48秒,所有其他代码都相同。

答案 1 :(得分:1)

如果您不想要特定方法并避开列表,请执行此操作。

var filteredWholeSale = wholeSaleEntry.Where(x => productList.Any(itemx => itemx.AlternateID == x.EAN || itemx.AlternateID == x.SKU));