如何从另一个列表中存在的结构列表中删除项目

时间:2013-05-05 00:49:38

标签: c# collections duplicate-removal

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<string>上运行得很好,但没有与List<RegistryApp>一起使用。

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);
    }
}

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

2 个答案:

答案 0 :(得分:5)

<强> EDITED

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

  

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

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

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

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);
    }
    }

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

答案 1 :(得分: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 ExecptSee the MSDN for an example