【问题标题】:How to remove items from a List of Structs that exist in another List如何从另一个列表中存在的结构列表中删除项目
【发布时间】:2013-04-29 02:54:36
【问题描述】:
public struct RegistryApp
{
    public string VendorName;
    public string Name;
    public string Version;
} 

我有两个List<RegistryApp>,其中包含当前安装在 Windows 机器上的所有应用程序。为什么是两个?好吧,我有一个列表来保存所有 x86 应用程序和一个列表来保存所有 x64 应用程序。

List<RegistryApp> x64Apps64List = new List<RegistryApp>();
List<RegistryApp> x64Apps32List = new List<RegistryApp>();

一旦这两个填充了从注册表中检索到的相应数据,我会尝试以下操作以确保没有重复项。这在 List&lt;string&gt; 上运行良好,但不适用于 List&lt;RegistryApp&gt;

List<RegistryApp> ListOfAllAppsInstalled = new List<RegistryApp>();

IEnumerable<RegistryApp> x86Apps = x64Apps32List.Except(x64Apps64List);
IEnumerable<RegistryApp> x64Apps = x64Apps64List.Except(x64Apps32List);

foreach (RegistryApp regitem in x86Apps)
{
    if ((regitem.Name != null) && 
     (regitem.Name.Length > 2) && 
     (regitem.Name != "")) 
    {
        ListOfAllAppsInstalled.Add(regitem);
    }
}

foreach (RegistryApp regitem in x64Apps) 
{
    if ((regitem.Name != null) && 
     (regitem.Name.Length > 2) && 
     (regitem.Name != "")) 
    {
        ListOfAllAppsInstalled.Add(regitem);
    }
}

有什么办法可以解决这个问题?

【问题讨论】:

    标签: c# collections duplicate-removal


    【解决方案1】:

    已编辑

    要从存在于另一个列表中的结构列表中删除项目,您可以在此处查看Cuong Le 提供的解决方案:

    https://stackoverflow.com/a/12784937/1507182

    通过对 List 类型使用 Distinct 无参数扩展方法,我们可以删除那些重复的元素。

    然后,我们可以选择调用 ToList 扩展来获取删除重复项的实际列表。

    static void Main()
        {
        // List with duplicate elements.
        List<int> mylist = new List<int>();
        mylist.Add(1);
        mylist.Add(2);
        mylist.Add(3);
        mylist.Add(3);
        mylist.Add(4);
        mylist.Add(4);
        mylist.Add(4);
    
        foreach (int value in mylist)
        {
            Console.WriteLine("Before: {0}", value);
        }
    
        // Get distinct elements and convert into a list again.
        List<int> distinct = mylist.Distinct().ToList();
    
        foreach (int value in distinct)
        {
            Console.WriteLine("After: {0}", value);
        }
        }
    

    如果我的回答解决了您的问题,请单击“接受为解决方案”按钮,这样做会帮助其他人知道解决方案。

    【讨论】:

      【解决方案2】:

      对于Execpt,您使用它的东西必须是可比较的。要使其适用于您的自定义结构,您需要执行以下两项操作之一,即覆盖 GetHashCodeEquals 以便能够将 Execpt 与您的结构一起使用:

      public struct RegistryApp
      {
          public string VendorName;
          public string Name;
          public string Version;
      
          public override bool Equals(object obj) 
          {
             if (!(obj is MyStruct))
                return false;
      
             RegistryApp ra = (RegistryApp) obj;
      
             return ra.VendorName == this.VendorName &&
                    ra.Name == this.Name &&
                    ra.Version == this.Version;
      
          }
      
          public override int GetHashCode()
          {
              return VendorName.GetHashCode() ^ Name.GetHashCode() ^ Version.GetHashCode();
          }
      
      } 
      

      或使用overload of Execpt,它允许您传入自己的比较器并将其传入。See the MSDN for an example

      【讨论】:

      • 我明白为什么我现在得到了 -1,我已经修正了措辞。
      • 这看起来可以工作,但我无法让它工作,我测试了奥巴马的代码并且它工作了,我确实需要做一些改变:List&lt;RegistryApp&gt; UniqueEntries = ListOfAllAppsInstalled.Distinct().ToList&lt;RegistryApp&gt;();
      猜你喜欢
      • 1970-01-01
      • 2011-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多