从列表2中筛选列表1

Sae*_*ari 2 c# linq list filter

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

我得到List包含(50k项目)和List包含(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; }
}
Run Code Online (Sandbox Code Playgroud)

和ProductList

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

}
Run Code Online (Sandbox Code Playgroud)

我需要通过它的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;
    }
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*r B 6

使用.Where(...).ToList()会找到每个匹配的项目,最后你只需要知道是否有匹配的项目.Any(...)一旦找到匹配,就可以使用哪个停止来修复,如下所示:

var hasAny = productList.Any(itemx => itemx.AlternateID == productEan || itemx.AlternateID == productSku);
if (hasAny)
{
    list.Add(item);
}
Run Code Online (Sandbox Code Playgroud)


更新:算法可以简化为此.首先使用a来获取唯一的备用ID HashSet,它只存储一次重复的项目,并且对于查找而言是快速疯狂的.然后获取与之匹配的所有WholeSale项目.
没有更快的策略,代码很小,我觉得很容易理解.

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;
Run Code Online (Sandbox Code Playgroud)

快速测试显示,对于5万+50k物品,使用HashSet<string>花了28ms来得到答案.使用List<string>填充使用.Distinct().ToList()需要48秒,所有其他代码相同.

  • 这在理论上听起来不错,但最糟糕的情况仍然是在所有120k项目上循环50k次. (2认同)