Remove duplicate inner lists from a list of list<object> in c#

前端 未结 2 1884
不知归路
不知归路 2020-12-21 14:49

I apologize for the ambiguous title. I couldn\'t keep it clear and concise at the same time. So feel free to change it.

I have a big List which contains several othe

相关标签:
2条回答
  • 2020-12-21 14:59

    I would implement a custom IEqualityComparer<IEnumerable<Column>> which you can use for Distinct:

    public class ColumnListComparer : IEqualityComparer<IEnumerable<Column>>
    {
        public bool Equals(IEnumerable<Column> x, IEnumerable<Column> y)
        {
            if (x == null || y == null) return false;
            if (object.ReferenceEquals(x, y)) return true;
            return x.SequenceEqual(y);
        }
    
        public int GetHashCode(IEnumerable<Column> obj)
        {
            unchecked
            {
                int hash = 17;
                foreach(Column col in obj)
                {
                    hash = hash * 23 + (col == null ? 0 : col.GetHashCode());
                }
                return hash;
            }
        }
    }
    

    Now this works:

    var result = listOfAllColumns.Distinct(new ColumnListComparer());
    

    You also need to override Equals + GetHashCode in your class Column:

    public class Column
    {
        public string SectionName;
        public string StirrupType;
        public int StirrupSize;
        public double StirrupSpacing;
    
        public override bool Equals(object obj)
        {
            Column col2 = obj as Column;
            if(col2 == null) return false;
            return SectionName    == col2.SectionName
                && StirrupType    == col2.StirrupType 
                && StirrupSize    == col2.StirrupSize
                && StirrupSpacing == col2.StirrupSpacing;
        }
    
        public override int GetHashCode()
        {
            unchecked
            {
                int hash = 17;
                hash = hash * 23 + (SectionName ?? "").GetHashCode();
                hash = hash * 23 + (StirrupType ?? "").GetHashCode();
                hash = hash * 23 + StirrupSize.GetHashCode();
                hash = hash * 23 + StirrupSpacing.GetHashCode();
                return hash;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-21 15:06

    What you need is an IEqualityComparer that is able to compare different sequences. This isn't terribly hard, given that it also has a way of comparing the items within it:

    public class SequenceComparer<T> : IEqualityComparer<IEnumerable<T>>
    {
        private IEqualityComparer<T> comparer;
        public SequenceComparer(IEqualityComparer<T> comparer = null)
        {
            this.comparer = comparer ?? EqualityComparer<T>.Default;
        }
        public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
        {
            return x.SequenceEqual(y, comparer);
        }
    
        public int GetHashCode(IEnumerable<T> sequence)
        {
            unchecked
            {
                int hash = 19;
                foreach (var item in sequence)
                    hash = hash * 79 + comparer.GetHashCode(item);
                return hash;
            }
        }
    }
    

    Now all you need to do is create an IEqualityComparer<Column> that is capable of comparing two column objects (through whatever meaningful way you want, presumably the default implementation is not sufficient).

    Then you can just pass those to Distinct:

    var query = listOfAllColumns.Distinct(
        new SequenceComparer<Column>(new ColumnComparer()));
    
    0 讨论(0)
提交回复
热议问题