【问题标题】:Remove non unique objects between two lists C#删除两个列表之间的非唯一对象 C#
【发布时间】:2021-07-27 14:16:46
【问题描述】:

我有两个对象列表,我想在我的第一个列表中删除第二个列表'对象的所有外观。基本上,获取 1st list 中相对于 2nd list 的所有唯一值(这些列表本身没有重复项)。表达这个问题的另一种方式是:如何在我的自定义列表上使用列表函数。我已经阅读过,人们建议重写 Equals 函数,我已经这样做了,但它并没有帮助我。我目前拥有的: filteredEntriesactuallyFilteredEntries 与 start 相同,entries 是一个独立的列表。 (我尝试使用 actuallyFilteredEntries 基本上是 filteredEntries 的副本,我可以在其中删除条目或以其他方式操作数据。

                for (int i = 0; i < entries.Count; i++)
                {
                    for (int j = 0; j < filteredEntries.Count; j++)
                    {
                        if (filteredEntries[j].Equals(entries[i]))
                        {
                            duplicateCount++;
                            // prints false
                            Console.WriteLine(actuallyFilteredEntries.Remove(filteredEntries[j]));

                        }
                    }
                }

这就是我希望它工作的方式,但显然您必须在 Remove() f.e. 中使用相同的对象。 actuallyFilteredEntries.Remove(actuallyFilteredEntries[j])。问题是,我遇到了索引越界错误。 我也尝试了 LINQ 方法,但无济于事

var etc = actuallyFilteredEntries.Except(entries);

预期结果:我留下了一个唯一值列表,现实:(它保存了所有 actuallyFilteredEntries 而不会丢弃任何 entries)。

我将添加我的 Equals()GetHashCode() 方法覆盖,也许其中有一些我没能找到的错误:

        public bool Equals(Entry entry)
        {
            if (Object.ReferenceEquals(entry, null))
            {
                return false;
            }
            if (this.GetType() != entry.GetType())
                return false;

            return (Desired_due_date == entry.Desired_due_date) && (Order_number== entry.Order_number) && (Series_number == entry.Series_number)
                && (Product_name == entry.Product_name) && (Product_code == entry.Product_code) && (ProcessesID== entry.ProcessesID)
                && (Ordered_amount== entry.Ordered_amount) && (Amount_made== entry.Amount_made) && (Start_date== entry.Start_date);
        }
        public override int GetHashCode()
        {
            return this.Desired_due_date.GetHashCode() ^ this.Order_number.GetHashCode() ^ this.Series_number.GetHashCode() ^ this.Product_name.GetHashCode()
                ^ this.Product_code.GetHashCode() ^ this.ProcessesID.GetHashCode() ^ this.Ordered_amount.GetHashCode() ^ this.Amount_made.GetHashCode()
                ^ this.Start_date.GetHashCode();
        }

感谢任何帮助或想法,无论我如何做(效率等),我只需要两个列表中的唯一列表。

【问题讨论】:

  • 是否有可能当对象在列表中时,您正在修改提供给散列函数的任何属性?
  • 是否还需要重写Equals(Object obj) 方法?
  • @HansKesting 是的,我错过了。还不知道它是否完全解决了问题,但到目前为止看起来不错,正在测试它,谢谢。
  • 可能更好的主意是为类编写扩展而不是覆盖现有方法
  • 另外,请确保您正在实施IEquatable&lt;T&gt;。平等优先是这样的。 1:显式 IEqualityComparer 参数 2:IEquatable.Equals,3. Object.Equals 4. ReferenceEquals 或自动值相等。

标签: c# list linq equals


【解决方案1】:

var etc = actuallyFilteredEntries.Union(entries)

可在此处找到相关文档:.Union MS Docs

返回 IEnumerable 一个 IEnumerable,包含两个输入序列中的元素,不包括重复项。

【讨论】:

    【解决方案2】:

    没有 LINQ 的回答:

    var seen = new HashSet<T>(filteredEntries);
    for (var i = 0; i < entries.Count; i++)
    {
      if (seen.Contains(entries[i]))
      {
        entries.RemoveAt(i);
        i--;
      }
    }
    

    【讨论】:

      【解决方案3】:

      借助 LINQ 联合运算符,您可以实现它。
      请检查以下代码。

      List<string> objList_1 = new List<string>() {"A","B","C","D" };
      List<string> objList_2 = new List<string>() { "A", "B", "E", "F" };
      var vUniqueList = objList_1.Intersect(objList_2).ToList();
      
      ======OutPut ============
      "A"
      "B"
      

      如果您只想要两个列表中的唯一值,请检查以下代码

      var result = objList_1.Except(objList_2).Concat(objList_2.Except(objList_1)).ToList();
      
      ====Output=======
      "C"
      "D"
      "E"
      "F"
      

      【讨论】:

      • stackoverflow 还支持 markdown,可以更轻松地格式化答案 - 查看格式化 manual
      • 再一次 - 无需在此处添加图片)
      猜你喜欢
      • 1970-01-01
      • 2013-06-27
      • 2022-08-14
      • 1970-01-01
      • 2019-06-13
      • 2012-06-21
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多