Ibrahem Hamdy Naeem - 1 year ago 66

C# Question

`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`

`x.X = 16.83897`

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:

`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)}) .Distinct().ToList();`

`Distinct`

and override`Equals`

and`GetHashCode`

- (equals will do the rounding) - wouldn't suggest`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(); } } //Use: myList.Distinct(new RoundedXyzComparer(5));`