【问题标题】:Compare two lists and add missing items by specific criteria比较两个列表并按特定条件添加缺失的项目
【发布时间】:2017-02-02 12:09:50
【问题描述】:

我写了如下代码:

foreach (var itemA in itm)
{
    foreach (var itemB in filteredList)
    {
        if (itemA.ItemID != itemB.ItemID)
        {
            missingList.Add(itemB);
            ListToUpdate.Add(itemB);
        }
        else
        {
            if (itemA.QuantitySold != itemB.QuantitySold)
            {
                ListToUpdate.Add(itemB);
            }
        }
    }
}

如您所见,我在这里有两个列表,它们的结构相同,它们是:

List #1 is "itm" list - which contains old records from DB

List #2 is "filteredList" - which has all items from DB and + new ones

我正在尝试根据下一个条件将项目添加到 missingList 和 ListToUpdate:

All items that are "new" in filteredList - meaning their ItemID doens't exists in  "itm" list should be added to missingList.

And all items that are new in filteredList- filteredList - meaning their ItemID doens't exists in  "itm" list should be added to .ListToUpdate

And final criteria to add items to ListToUpdate should be those items that exist in both lists - and if the quantitysold in "itm" list is different - add them to ListToUpdate

我写的上面的代码给了我完全错误的结果,我最终在两个列表中都有超过 50000 个额外的项目......

我想按照我上面写的那样工作的方式更改此代码,并可能使用并行循环或 PLINQ 来加快速度...

有人可以帮帮我吗?

【问题讨论】:

  • 简而言之,您有两个列表,为仅存在于过滤列表中的 ID 创建一个新列表,并为两个列表中都存在的 ID 创建另一个列表 (ListToUpdate)。对吗?
  • 您应该为每个标准编写一个方法来接收问题的 3 个子集,然后组合结果。奖励:这 3 种方法可以并行运行。
  • @Anand 是的,这是正确的,对第二个列表稍作更改 - 为两个列表中都存在的 ID 创建另一个列表(ListToUpdate),但只有那些具有不同 QuantitySold 属性的 ID,这意味着 ItemID 来自新列表的销售数量多于旧列表中的 ItemID (db)
  • @Dawnkeeper 你能给我举个例子吗?

标签: c# list c#-4.0 parallel-processing compare


【解决方案1】:

让我们使用Parallel.ForEach,它在 C# 4.0 中可用:

    Parallel.ForEach(filteredList, (f) =>
    {
        var conditionMatchCount = itm.AsParallel().Max(i =>
        // One point if ID matches
        ((i.ItemID == f.ItemID) ? 1 : 0) +
        // One point if ID and QuantitySold match
        ((i.ItemID == f.ItemID && i.QuantitySold == f.QuantitySold) ? 1 : 0)
        );

        // Item is missing
        if (conditionMatchCount == 0)
        {
            listToUpdate.Add(f);
            missingList.Add(f);
        }
        // Item quantity is different
        else if (conditionMatchCount == 1)
        {
            listToUpdate.Add(f);
        }
    });

上面的代码使用了两个嵌套的并行列表迭代器。

【讨论】:

    【解决方案2】:

    以下是比较两个列表的示例,它将为您提供新 ID 列表。

    我用来保存数据的类

     public class ItemList
    {
        public int ID { get; set; }
    }
    

    获取新 ID 的功能

    private static void GetNewIdList()
        {
            List<ItemList> lstItm = new List<ItemList>();
            List<ItemList> lstFiltered = new List<ItemList>();
    
            ItemList oItemList = new ItemList();
            oItemList.ID = 1;
            lstItm.Add(oItemList);
            lstFiltered.Add(oItemList);
    
            oItemList = new ItemList();
            oItemList.ID = 2;
            lstItm.Add(oItemList);
            lstFiltered.Add(oItemList);
    
            oItemList = new ItemList();
            oItemList.ID = 3;
            lstFiltered.Add(oItemList);
    
            var lstListToUpdate = lstFiltered.Except(lstItm);
    
    
            Console.WriteLine(lstListToUpdate);
        }
    

    要获取常用 ID 列表,请使用以下

      var CommonList = from p in lstItm
                             join q in lstFiltered
                             on p.ID equals q.ID
                             select p;
    

    更新 2 用于根据 ID 从过滤列表中获取新 ID 列表

     var lstListToUpdate2 = lstFiltered.Where(a => !lstItm.Select(b => b.ID).Contains(a.ID));
    

    【讨论】:

    • Except 方法根据哪些标准比较两个列表?由于我的类类型是从 EF 生成的,我应该重写 except 方法,以便我可以比较特定属性的 2 个列表?
    • 我已经在上面的代码中粘贴了更新以指定属性。
    猜你喜欢
    • 1970-01-01
    • 2017-08-28
    • 2019-08-04
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多