Использование Round
может создать ситуацию, когда два числа, хотя и невероятно близкие друг к другу, могут в конечном итоге считаться отличными.
Возьмем такой пример:
var Mylist = new []
{
new { X = 1.0000051, Y = 1.0 },
new { X = 1.0000049, Y = 1.0 },
new { X = 1.1, Y = 1.0 },
new { X = 1.0, Y = 1.005 },
};
Первые два значения очень близки - ведь они отличаются в 6-ом знаке после запятой.
По что, если мы запустим этот код:
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();
Результат:
Округление позволило эти два значения должны быть сохранены.
Правильный подход заключается в фильтрации по расстоянию. Если последующее значение находится в пределах порогового значения предыдущих значений, оно должно быть отброшено.
Вот код, который делает это:
var threshold = 0.000001;
Func<double, double, double, double, double> distance
= (x0, y0, x1, y1) =>
Math.Sqrt(Math.Pow(x1 - x0, 2.0) + Math.Pow(y1 - y0, 2.0));
var result = Mylist.Skip(1).Aggregate(Mylist.Take(1).ToList(), (xys, xy) =>
{
if (xys.All(xy2 => distance(xy.X, xy.Y, xy2.X, xy2.Y) >= threshold))
{
xys.Add(xy);
}
return xys;
});
Теперь, если мы управляем, что на данных Mylist
мы получаем это:
Это лучше подходит для удаления дубликатов.
Проблема кажется довольно прямой - что вы пробовали, и где именно у вас проблемы? –
Просто добавьте соответствующее округление в 'new {x.X, ...}' – CSharpie
, некоторые дубликаты были удалены, где три компонента x, y, z для двух точек, как правило, одинаковы. но когда, например, если x = 1.1111111111109 и x = 1.1111111111108, эти две точки остаются, поэтому я спрашиваю, могу ли я добавить условие раунда в том же самом заявлении выше! –