Ibrahem Hamdy Naeem Ibrahem Hamdy Naeem - 1 year ago 126
C# Question

Remove duplicates in a list of XYZ points

Mylist.GroupBy(x => new{x.X, x.Y}).Select(g => g.First()).ToList<XYZ>();

The above code works fine with me. I only want to compare the points based on the round(5) of the point component.

For example
x.X = 16.838974347323224
, I would it to compare only
x.X = 16.83897
cause I experienced some inaccuracy after the round 5. Any suggestions?

Update :
solved by implementing

Mylist.GroupBy(x => new { X = Math.Round(x.X,5), Y = Math.Round(x.Y,5) })
.Select(g => g.First()).ToList();

Answer Source

To do so use Math.Round:

var result = Mylist.GroupBy(x => new { X = Math.Round(x.X,5, MidpointRounding.AwayFromZero), Y = Math.Round(x.Y,5, MidpointRounding.AwayFromZero) })
                   .Select(g => g.First()).ToList();

However if what you want is to remove duplicates then instead of GroupBy go for one of these:

  1. Select rounded and then Distinct:

    var result = Mylist.Select(item => new XYZ { X = Math.Round(item.X,5, MidpointRounding.AwayFromZero), 
                                                 Y = Math.Round(item.Y,5, MidpointRounding.AwayFromZero)})
  2. Distinct and override Equals and GetHashCode - (equals will do the rounding) - wouldn't suggest

  3. Distinct and implement a custom IEqualityComparer:

    public class RoundedXyzComparer : IEqualityComparer<XYZ>
        public int RoundingDigits { get; set; }
        public RoundedXyzComparer(int roundingDigits)
           RoundingDigits = roundingDigits;
        public bool Equals(XYZ x, XYZ y)
           return Math.Round(x.X, RoundingDigits, MidpointRounding.AwayFromZero) == Math.Round(y.X, RoundingDigits, MidpointRounding.AwayFromZero) && 
                  Math.Round(x.Y,RoundingDigits, MidpointRounding.AwayFromZero) == Math.Round(y.Y, RoundingDigits, MidpointRounding.AwayFromZero);
        public int GetHashCode(XYZ obj)
           return Math.Round(obj.X, RoundingDigits, MidpointRounding.AwayFromZero).GetHashCode() ^
                  Math.Round(obj.Y, RoundingDigits, MidpointRounding.AwayFromZero).GetHashCode();
     myList.Distinct(new RoundedXyzComparer(5));
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download