在C#中比较两个列表是否存在重复项

3

我有两个列表,如下所示:

List<EmpData> colExistingEmpData;
List<EmpData> colExternalEmpData;

每个员工都会有相同的Id,这些员工记录将被存储。

对于colExternalEmpData中的每个员工,会对colExistingEmpData进行EmpId检查。

foreach (EmpData employee in colExternalEmpData)
{
  var queryResult = colExistingEmpData.FindAll(thisEmployee => thisEmployee.Id == employee.Id);

  if(querResult.count == 0)
  {
    // Mark as INSERT
  } 
  else if(querResult.count == 1)
  {
    // Mark as UPDATE
  }
  else // queryResult is more than 1
  {
    // data is duplicated mark as IGNORE
  }

  analysedData.Add(employee);

如果colExistingEmpData的“Id”没有重复值,那么这个方法就可以很好地运行。

当colExternalEmpData中存在重复的记录时,例如两个员工的“Id”都是123,则上述代码仍将标记具有123 ID的现有员工为更新,因为它在colExistingEmpData中找到了一个完全匹配项(只要colExistingEmpData中有一个与该Id相同的记录)。

是否有一种方法可以标记在任一来源中重复的员工记录为“IGNORE”?

我不能使用Dictionary对象,之前我曾经用过,但是领导不喜欢这个想法。

祝好。


1
“标记为IGNORE”是什么意思?为什么不能使用一个包含所有重复ID的HashSet?此外,您的查询将在此处运行两次。使用ToList只运行一次 ;) - Evelie
1
这是你的确切代码吗?FindAll返回一个列表,而不是整数,对吧? - YavgenyP
我之前用过它,但是当权者似乎不太喜欢这个想法。这是我必须承认的新事物。你的同行们是否也喜欢应用程序变得缓慢和卡顿呢?在这种情况下,使用字典可以获得最快的结果(至少在渐进意义下)。 - vgru
@Groo,你在用“慢”和“卡顿”这些词形容我的同行时非常宽容,他们更喜欢下达命令。 - Codehelp
@Michael:我想你是对的,我有幸在一些鼓励良好编程实践(至少是常识)的地方工作。如果那是一个大而糟糕的组织,那么我可能会被迫创建一个大而糟糕的演示文稿,比较列表查找和字典查找的性能。这样的教条主义规则只会降低效率,最终降低产品质量。 - vgru
显示剩余2条评论
4个回答

2
考虑将已处理的列表加入到这个方程中:
List<int> processed = new List<int>();

然后在循环的顶部添加以下代码:

if (processed.Contains(employee.Id)) { continue; }
processed.Add(employee.Id);

所以在检查另一个列表之前,您需要先执行此操作。这是您首先要做的事情,因为您并不真正关心它是否已被处理。


这相当于在他的最后一个else中只放置continue;。我认为他想出于某种原因标记重复项,而不仅仅是跳过它们。 - Evelie
@Evelie,问题在于员工在第一个列表中出现了两次,而这个列表正在被迭代。 - Mike Perrenoud

1
假设我正确理解了您的问题,您可以始终按照员工ID对ExternalList进行排序,然后不使用Foreach循环,而是使用while循环,并在ID相同时跳过员工。
以下是代码示例,已化简为整数:
List<int> external = new List<int>() { 1, 2, 2, 5, 1, 3 };
List<int> internalList = new List<int>() { 1, 4, 5, 3 };
external.Sort();
int index = 0;
int item = -1;
while (index < external.Count)
{
    if (external[index] != item)
    {
       item = external[index];
       internalList.FindAll(t => t == item);
    }
    index++;
 }

0
另一种方法是重写 EqualsGetHashCode 方法,然后使用 .Distinct()

MSDN


0

基本上 OP 需要知道,逐行如何处理它。虽然将这两个列表连接起来可以去除重复项,但并不能真正解决根据第二个列表中的存在情况处理每一行的需求。 - Mike Perrenoud
1
我花了5次尝试才理解那个问题,哈哈,我明白你的意思,你是正确的。 - Derek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接