-2

In a list of SchematicElevation objects how can I remove the ones with the same property using LINQ.

public class SchematicElevation
{
    public double Elevation { get; set; }
    public int ColumnId { get; set; }
}

var se1 = new SchematicElevation { ColumnId = 2, Elevation = 300 };
var se2 = new SchematicElevation { ColumnId = 3, Elevation = 300 };
var se3 = new SchematicElevation { ColumnId = 4, Elevation = 300 };
var se4 = new SchematicElevation { ColumnId = 4, Elevation = 300 };
var se5 = new SchematicElevation { ColumnId = 4, Elevation = 300 };

var SchematicElevations = new List<SchematicElevation> { se1, se2, se3, se4, se5}

The final result would be the list below:

List: {se1, se2, se3}

I would like doing this using LINQ and by using GroupBy.

Vahid
  • 5,144
  • 13
  • 70
  • 146

2 Answers2

2

You should implement equality, either directly on SchematicElevation or via an IEqualityComparer<T>. For example, using a hash algorithm from Jon Skeet:

public class SchematicElevation : IEquatable<SchematicElevation>
{
    public double Elevation { get; set; }
    public int ColumnId { get; set; }
    public override int GetHashCode()
    {
        unchecked // Overflow is fine, just wrap
        {
            int hash = 17;
            hash = hash * 23 + Elevation.GetHashCode();
            hash = hash * 23 + ColumnId.GetHashCode();
            return hash;
        }
    }
    public override bool Equals(object other)
    {
        return Equals(other as SchematicElevation);
    }
    public bool Equals(SchematicElevation other)
    {
        return other != null && this.Elevation == other.Elevation &&
               this.ColumnId == other.ColumnId;
    }
}

Then you simply have to do a Distinct() to get the distinct items:

var schematicElevations = new List<SchematicElevation> {se1, se2, se3, se4, se5};
var distinct = schematicElevations.Distinct();

Or, you could do a GroupBy. This makes for shorter code, but unlike the above, it is not reusable or very maintainable. E.g. if you want to change the criteria, you'd have to change this code everywhere it's used, instead of just the SchematicElevation class.

var schematicElevations = new List<SchematicElevation> {se1, se2, se3, se4, se5};
var distinct = schematicElevations.GroupBy(x => new { x.ColumnId, x.Elevation })
                                  .Select(g => g.First());
Community
  • 1
  • 1
Tim S.
  • 55,448
  • 7
  • 96
  • 122
0

I would highly recommend implementing IEquatable. Then you can use the method Distinct() that was designed to do what you want (instead of Group By which is not designed to do what you want, but still allows you to get there).

var result = SchematicElevations.Distinct();
Erik Philips
  • 53,428
  • 11
  • 128
  • 150