我有一个List,其中每个double []的长度为3.我想通过仅留下具有给定容差内的唯一元素的double []来清理此列表(向上舍入)。例如,列表如下:
1059.17 0 446.542225842081
1059.17 0 446.542564789741
1059.17 0 446.541759880305
959.167 0 579.827860527898
959.167 0 579.827847296075
对于给定的公差= 2,应该成为这个:
1059.17 0 446.54,
959.17 0 579.83,
有一种巧妙的方式可以做到这一点吗?
答案 0 :(得分:1)
假设数组元素的顺序始终相同,您可以创建自己的比较器,知道如何比较双数组:
public class MyDoubleArrComparer : IEqualityComparer<double[]>
{
public bool Equals(double[] x, double[] y)
{
for (int i = 0; i < x.Length; i++)
{
if (x[i] != y[i]) return false;
}
return true;
}
public int GetHashCode(double[] obj)
{
return base.GetHashCode();
}
}
您可以创建一个辅助方法来舍入数字并删除重复项:
public static class Helper
{
public static List<double[]> MyFilter(this List<double[]> list, int tolerance)
{
var result = list
.Select(arr =>
{
// rounds numbers with precision that is set in tolerance variable
arr = arr.Select(d => d = Math.Round(d, tolerance)).ToArray();
return arr;
}).Distinct(new MyDoubleArrComparer()) // here we use our custom comparer
.ToList();
return result;
}
}
现在我们可以开始使用我们的辅助方法:
var nums = new List<double[]>()
{
new[] {1059.17, 0, 446.542225842081},
new[] {1059.17, 0, 446.542564789741},
new[] {1059.17, 0, 446.541759880305},
new[] {959.167, 0, 579.827860527898},
new[] {959.167, 0, 579.827847296075},
};
var result = nums.MyFilter(2);
foreach (var arr in result)
{
foreach (var d in arr)
{
Console.Write(d + " ");
}
Console.WriteLine();
}
输出:
1059.17 0 446.54
959.17 0 579.83
答案 1 :(得分:1)
这应该有效。它使用匿名类型的内置相等比较。
List<double[]> data = ...
int tolerance = 2;
var roundedData = data
.Select(x => new {
v1 = Math.Round(x[0], tolerance),
v2 = Math.Round(x[1], tolerance),
v3 = Math.Round(x[2], tolerance)
})
.Distinct()
.Select(x => new [] { x.v1, x.v2, x.v3 })
.ToList();
答案 2 :(得分:0)
也许这会有用吗?
public List<double[]> CleanWithTolerance(List<double[]> doubleNumbersList, int tolerance)
{
var newDoublesNumbersList = new List<double[]>();
foreach(double[] doubleNumbers in doubleNumbersList)
{
var newDoublesNumbers = doubleNumbers.Select(doubleNumber => Math.Round(doubleNumber, tolerance)).ToArray();
if(newDoublesNumbersList.All(cleanDoubleNumbers => !Enumerable.SequenceEqual(cleanDoubleNumbers, newDoublesNumbers))
{
newDoublesNumbersList.Add(newDoublesNumbers);
}
}
return newDoublesNumbersList;
}