Remove duplicates from a List in C#

前端 未结 27 1808
广开言路
广开言路 2020-11-22 04:41

Anyone have a quick method for de-duplicating a generic List in C#?

相关标签:
27条回答
  • 2020-11-22 05:06

    There are many ways to solve - the duplicates issue in the List, below is one of them:

    List<Container> containerList = LoadContainer();//Assume it has duplicates
    List<Container> filteredList = new  List<Container>();
    foreach (var container in containerList)
    { 
      Container duplicateContainer = containerList.Find(delegate(Container checkContainer)
      { return (checkContainer.UniqueId == container.UniqueId); });
       //Assume 'UniqueId' is the property of the Container class on which u r making a search
    
        if(!containerList.Contains(duplicateContainer) //Add object when not found in the new class object
          {
            filteredList.Add(container);
           }
      }
    

    Cheers Ravi Ganesan

    0 讨论(0)
  • 2020-11-22 05:12

    It worked for me. simply use

    List<Type> liIDs = liIDs.Distinct().ToList<Type>();
    

    Replace "Type" with your desired type e.g. int.

    0 讨论(0)
  • 2020-11-22 05:12

    Use Linq's Union method.

    Note: This solution requires no knowledge of Linq, aside from that it exists.

    Code

    Begin by adding the following to the top of your class file:

    using System.Linq;
    

    Now, you can use the following to remove duplicates from an object called, obj1:

    obj1 = obj1.Union(obj1).ToList();
    

    Note: Rename obj1 to the name of your object.

    How it works

    1. The Union command lists one of each entry of two source objects. Since obj1 is both source objects, this reduces obj1 to one of each entry.

    2. The ToList() returns a new List. This is necessary, because Linq commands like Union returns the result as an IEnumerable result instead of modifying the original List or returning a new List.

    0 讨论(0)
  • 2020-11-22 05:13

    In Java (I assume C# is more or less identical):

    list = new ArrayList<T>(new HashSet<T>(list))
    

    If you really wanted to mutate the original list:

    List<T> noDupes = new ArrayList<T>(new HashSet<T>(list));
    list.clear();
    list.addAll(noDupes);
    

    To preserve order, simply replace HashSet with LinkedHashSet.

    0 讨论(0)
  • 2020-11-22 05:13

    If you don't care about the order you can just shove the items into a HashSet, if you do want to maintain the order you can do something like this:

    var unique = new List<T>();
    var hs = new HashSet<T>();
    foreach (T t in list)
        if (hs.Add(t))
            unique.Add(t);
    

    Or the Linq way:

    var hs = new HashSet<T>();
    list.All( x =>  hs.Add(x) );
    

    Edit: The HashSet method is O(N) time and O(N) space while sorting and then making unique (as suggested by @lassevk and others) is O(N*lgN) time and O(1) space so it's not so clear to me (as it was at first glance) that the sorting way is inferior (my apologies for the temporary down vote...)

    0 讨论(0)
  • 2020-11-22 05:16

    If you have tow classes Product and Customer and we want to remove duplicate items from their list

    public class Product
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
    }
    
    public class Customer
    {
        public int Id { get; set; }
        public string CustomerName { get; set; }
    
    }
    

    You must define a generic class in the form below

    public class ItemEqualityComparer<T> : IEqualityComparer<T> where T : class
    {
        private readonly PropertyInfo _propertyInfo;
    
        public ItemEqualityComparer(string keyItem)
        {
            _propertyInfo = typeof(T).GetProperty(keyItem, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public);
        }
    
        public bool Equals(T x, T y)
        {
            var xValue = _propertyInfo?.GetValue(x, null);
            var yValue = _propertyInfo?.GetValue(y, null);
            return xValue != null && yValue != null && xValue.Equals(yValue);
        }
    
        public int GetHashCode(T obj)
        {
            var propertyValue = _propertyInfo.GetValue(obj, null);
            return propertyValue == null ? 0 : propertyValue.GetHashCode();
        }
    }
    

    then, You can remove duplicate items in your list.

    var products = new List<Product>
                {
                    new Product{ProductName = "product 1" ,Id = 1,},
                    new Product{ProductName = "product 2" ,Id = 2,},
                    new Product{ProductName = "product 2" ,Id = 4,},
                    new Product{ProductName = "product 2" ,Id = 4,},
                };
    var productList = products.Distinct(new ItemEqualityComparer<Product>(nameof(Product.Id))).ToList();
    
    var customers = new List<Customer>
                {
                    new Customer{CustomerName = "Customer 1" ,Id = 5,},
                    new Customer{CustomerName = "Customer 2" ,Id = 5,},
                    new Customer{CustomerName = "Customer 2" ,Id = 5,},
                    new Customer{CustomerName = "Customer 2" ,Id = 5,},
                };
    var customerList = customers.Distinct(new ItemEqualityComparer<Customer>(nameof(Customer.Id))).ToList();
    

    this code remove duplicate items by Id if you want remove duplicate items by other property, you can change nameof(YourClass.DuplicateProperty) same nameof(Customer.CustomerName) then remove duplicate items by CustomerName Property.

    0 讨论(0)
提交回复
热议问题