代码之家  ›  专栏  ›  技术社区  ›  mr_blond

如何从带有LINQ的列表中删除具有两个重复属性组合的对象?

  •  1
  • mr_blond  · 技术社区  · 7 年前

    同一个问题 this one 但我需要从列表中删除具有两个重复属性组合的对象。

    有一组对象,对象有年龄和名称:

    21 Carl
    23 Vladimir
    25 Bob
    21 Olivia
    21 Carl
    30 Jacob
    23 Vladimir
    

    输出列表应包含:

    21 Carl
    23 Vladimir
    25 Bob
    21 Olivia
    30 Jacob
    

    如何删除它?

    3 回复  |  直到 7 年前
        1
  •  1
  •   NaDeR Star    7 年前

    试试这个:

      public class KeyValueClass
        {
            public int Age { get; set; }
            public string Name { get; set; }
        }
    
        private void DoTheJob()
        {
    
            var myList = new List<KeyValueClass>
            {
                new KeyValueClass {Age = 21, Name = "Carl"},
                new KeyValueClass {Age = 23, Name = "Vladimir"},
                new KeyValueClass {Age = 25, Name = "Bob"},
                new KeyValueClass {Age = 21, Name = "Olivia"},
                new KeyValueClass {Age = 21, Name = "Carl"},
                new KeyValueClass {Age = 30, Name = "Jacob"},
                new KeyValueClass {Age = 23, Name = "Vladimir"},
            };
    
            var myDistinctList = myList.GroupBy(x => new { x.Age, x.Name })
                .Select(c => c.First()).ToList();
        }
    
        2
  •  1
  •   Codigo    7 年前

    可以使用Linq命名空间中的distinct()和IEqualityComparer:

    class Program
    {
        static void Main(string[] args)
        {
    
    
            List<KeyValueClass> myList = new List<KeyValueClass>
                {
                    new KeyValueClass {Age = 21, Name = "Carl"},
                    new KeyValueClass {Age = 23, Name = "Vladimir"},
                    new KeyValueClass {Age = 25, Name = "Bob"},
                    new KeyValueClass {Age = 21, Name = "Olivia"},
                    new KeyValueClass {Age = 21, Name = "Carl"},
                    new KeyValueClass {Age = 30, Name = "Jacob"},
                    new KeyValueClass {Age = 23, Name = "Vladimir"},
                };
    
            var myDistincList = myList.Distinct(new KeyValueEqualityComparer());
    
            foreach (var item in myDistincList) { Console.WriteLine("Age: {0}, Name:{1}", item.Age, item.Name); }
    
            Console.ReadKey();
        }
    }
    
    
    public class KeyValueClass 
    {
        public int Age { get; set; }
        public string Name { get; set; }
    }
    
    
    
    class KeyValueEqualityComparer : IEqualityComparer<KeyValueClass>
    {
        public bool Equals(KeyValueClass x, KeyValueClass y)
        {
            if (x == null || y == null) return false;
            if (x.Age == y.Age && x.Name.Equals(y.Name)) return true;
            return false;
        }
    
        public int GetHashCode(KeyValueClass obj)
        {
            return (obj.Age + obj.Name).GetHashCode() + 387;
        }
    }
    
        3
  •  0
  •   Travis Primm    7 年前

    只需使用ISET就可以避免列表的开销和缓慢的性能:

    public class Person : IEquatable<Person> 
    {
        public int Age { get; private set;}
        public string Name { get; private set;}
    
        public bool override Equals(Person other){
            return other.Age == Age && other.Name.Equals(Name);
        }
    
        public override int GetHashCode(){
            return Age.GetHashCode() ^ Name.GetHashCode();
        }
    }
    
    private IEnumerable<Person> MakeUniqueList(IEnumerable<Person> input){
        return new HashSet<Person>(input);
    }
    

    为了实际删除,这将是相当慢的性能(但它将节省内存使用),请使用list.remove(t) https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.remove?view=netframework-4.7.2