如何使用LINQ联合List <t>?</t>

时间:2012-10-10 06:34:23

标签: c# linq list

我有两个List实例,即OldCustomers,NewCustomers。

List<Customer> OldCustomers;

List<Customer> NewCustomers;

我只想要Oldcustomers,NewCustomers的联盟。也就是说,如果CustomerID 100存在于OldCustomerList中以及NewCustomer List中,那么必须删除OldCustomer List中的Customer Details,并且NewCustomer List必须放在结果列表中,如下所示。

List<Customer> NewCustomers;
    Union
List<Customer> OldCustomers;

我如何在LINQ中执行此操作?

先谢谢,

6 个答案:

答案 0 :(得分:1)

要使用Union,您必须自定义EqualityComparer

public class CusComparer : EqualityComparer<Customer>
{
    public override bool Equals(Customer x, Customer y)
    {
        return x.CustomerID == y.CustomerID;
    }

    public override int GetHashCode(Customer obj)
    {
        return obj.CustomerId.GetHashCode();
    }
}

然后:

var unionCustomers = NewCustomers.Union(OldCustomers, new CusComparer());

答案 1 :(得分:0)

你可以像这样使用联合函数

sequence1.Union(sequence2)

var custlist =  NewCustomers.Union(OldCustomers).ToList(); 

阅读:Enumerable.Union Method (IEnumerable, IEnumerable)

示例:

            int[] ints1 = { 5, 3, 9, 7, 5, 9, 3, 7 };
            int[] ints2 = { 8, 3, 6, 4, 4, 9, 1, 0 };

            IEnumerable<int> union = ints1.Union(ints2);

            foreach (int num in union)
            {
                Console.Write("{0} ", num);
            }

            /*
             This code produces the following output:

             5 3 9 7 8 6 4 1 0
            */

答案 2 :(得分:0)

您可以使用Union之类的

var union = NewCustomers.Union(OldCustomers);

您可能需要为Customer班级

实施自己的comparer

答案 3 :(得分:0)

Union将比较Customer对象的实例(如果未使用IEqualityComparer)。我想你正在寻找像UnionBy

这样的东西
var finalList = NewCustomers.Concat(OldCustomers)
                    .GroupBy(x => x.CustomerID)
                    .Select(x => x.First())
                    .ToList();

- 编辑 -

可能的UnionBy实施:

var finalList = NewCustomers.UnionBy(OldCustomers, c => c.CustomerID).ToList();

-

public static class SOExtension
{

    public static IEnumerable<T> UnionBy<T,V>(this IEnumerable<T> list, IEnumerable<T> otherList,Func<T,V> selector)
    {
        HashSet<V> set = new HashSet<V>();

        foreach (T t in list)
        {
            set.Add(selector(t));
            yield return t;
        }
        foreach(T t in otherList)
        {
            if(!set.Contains(selector(t)))
                yield return t;
        }
    }
}

答案 4 :(得分:0)

因此,您希望将所有新客户和所有不属于新列表的旧客户:

List<Customer> customers = NewCustomers.Concat(OldCustomers.Except(NewCustomers)).ToList();

请记住实施IEqualityComparer<T>通用界面来比较您的客户(可能是CustomerID)。因此,您需要为GetHashCode提供自己的EqualsCustomer方法。

这是一个可能的实现:

public class Customer 
{
    public int CustomerID { get; set; }
    public string CustomerName { get; set; }

    public override bool Equals(Object obj)
    {
        Customer cust = obj as Customer;
        if (cust == null) return false;
        return cust.CustomerID == CustomerID;
    }

    public override int GetHashCode()
    {
        return CustomerID.GetHashCode();
    }

    public class Comparer : IEqualityComparer<Customer>
    {
        public bool Equals(Customer x, Customer y)
        {
            if (x == null && y == null) return true;
            if (x == null || y == null) return false;
            return x.Equals(y);
        }

        public int GetHashCode(Customer obj)
        {
            if (obj == null) return -1;
            return obj.GetHashCode();
        }
    }
}

请注意,我会覆盖Equals中的GetHashCodeCustomer。通过这种方式,您甚至不需要将IEqualityComparer<Customer>的实例传递给Except(或允许传递比较器的任何其他方法)。

但为了完整起见,我还添加了实现接口的类Comparer,因此您也可以将它传递给Except:

NewCustomers.Concat(OldCustomers.Except(NewCustomers, new Customer.Comparer()));

答案 5 :(得分:0)

HashSet<Customer> set = new HashSet<Customer>(list1);
set.SymmectricExceptWith(list2); // Or other userful methods.