使用基于唯一ID的linq合并2个列表以避免重复

时间:2016-03-31 12:44:32

标签: c# linq

我有两个产品清单:产品和extraProducts 我的目标是合并2个列表,但避免基于Id的重复。

这是我最好的尝试:

List<Product> allProductsWithNoDuplicates = new List<Product>();

allProductsWithNoDuplicates.AddRange(products.Where(p => extraProducts.Select(ep => ep.Id).Contains(p.Id)).ToList());

然而它不起作用,因为它需要在NOT Contains的地方。

4 个答案:

答案 0 :(得分:3)

首先,创建一个IComparer类,

public class ProductComparer: IComparer 
{
  int IComparer.Compare(object a, object b)
 {
    if(a.Id == b.Id)
      return 0;
    else
     return 1;
 }
}

然后在连接两个列表后使用Distinct()。

allProductsWithNoDuplicates =   products.Concat(extraProducts).Distinct(new ProductComparer()).ToList();

答案 1 :(得分:1)

您可以将Union语句与IEqualityComparer一起使用。

https://msdn.microsoft.com/en-us/library/bb358407%28v=vs.100%29.aspx

要使用Union,您可以执行以下操作:

List<Product> myUniqueProducts = products.Union(extraProducts, new ProductEqualityComparer()).ToList();

它还提供了页面底部文档中的示例。

答案 2 :(得分:1)

这可以帮助你 - 它是一个控制台应用程序......

using System;
using System.Collections.Generic;
using System.Linq;

namespace SO
{
    class Program
    {
        public static void Main(string[] args)
        {
            var listA = new List<Product>();

            var listB = new List<Product>();

            listA.Add(new Product() {Id = 1, Name = "Hair Curling Tongs"});
            listA.Add(new Product() {Id = 2, Name = "Toys"});
            listA.Add(new Product() {Id = 3, Name = "Coffee"});

            listB.Add(new Product() {Id = 3, Name = "Dress"});
            listB.Add(new Product() {Id = 4, Name = "Handbag"});

            var results = listA.Union(listB).Distinct(new EqualityComparer()).ToList();

            foreach(var result in results)
            {
                Console.WriteLine("{0} ----- {1}", result.Id, result.Name);
            }

            // TODO: Implement Functionality Here

            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }

    class Product{
        public int Id{get; set;}
        public string Name {get; set;}
    }

    class EqualityComparer: IEqualityComparer<Product> {

        public bool Equals(Product p1, Product p2) {
            return p1.Id == p2.Id;
        }

        public int GetHashCode(Product p){
            return p.Id;
        }
    }
}

这对您来说似乎也是一个有用的链接 - http://www.elevenwinds.com/blog/linq-distinctby-with-lambda-expression-parameter/

答案 3 :(得分:0)

实际上Union在这里是最好的。您可以使用Distinct功能:

var allProductsWithNoDuplicates = products.Union(extraProducts).DistinctBy(x => x.Id);

这应该通过 Id 属性将两个列表合并为一个没有相同元素的列表。