我有一个List
doubles
有几个值靠近在一起,后面有一些相距甚远;例如:
2.151, 2.152, 2.155, 100.1, 100.13, ...
我在考虑以下几点:
if(abs(a[n] - a[n+1]) is within epsilon)
remove a[n+1] from a;
else continue;
获得类似的内容:
2.151, 100.1, ...
我可以编写一个Linq(或某种lambda表达式)来执行此操作吗?
答案 0 :(得分:0)
如果您不反对滚动自己的扩展方法,可以这样做:
public static IEnumerable<double> FuzzyDistinct(this IEnumerable<double> source, double epsilon)
{
// If source is null yield an empty enumerable.
if(source == null)
{
yield break;
}
// Get the source's enumerator.
var enumerator = source.GetEnumerator();
// If the source is empty yield an empty enumerator.
if(!enumerator.MoveNext())
{
yield break;
}
// Get the current item and yield it.
double current = enumerator.Current;
yield return current;
// Iterate over the remaining items, updating 'current' and yielding it
// if it does not fall within the epsilon of the previous value.
while(enumerator.MoveNext())
{
// Uncomment one of the following sections depending on
// your needs.
// Use this if the comparison is based on the previous
// item yielded.
//if(Math.Abs(enumerator.Current - current) > epsilon)
//{
// current = enumerator.Current;
// yield return current;
//}
// Use this if the comparison is based on the previous
// item, regardless of whether or not that item was yielded.
//if(Math.Abs(enumerator.Current - current) > epsilon)
//{
// yield return enumerator.Current;
//}
//current = enumerator.Current;
}
}
然后,例如,你会这样称呼它:
Enumerable
.Range(0, 10)
.Select(x => (double)x)
.FuzzyDistinct(1.5);
示例输出:
0 2 4 6 8
答案 1 :(得分:0)
这对我有用:
var numbers = new [] { 2.151, 2.152, 2.155, 100.1, 100.13, };
var epsilon = 0.003;
var reduced = numbers.Skip(1).Aggregate(numbers.Take(1).ToList(), (a, x) =>
{
if (Math.Abs(a.Last() - x) > epsilon)
{
a.Add(x);
}
return a;
});
这会为我返回{ 2.151, 2.155, 100.1, 100.13, }
。
答案 2 :(得分:-1)
LINQ中的任何内容都无法真正增强列表中的两个项目。我的意思是LINQ Where:
.Where(i => i.CustomerID == 1)
经常以单数形式进行交易,意味着单一项目评估,而不是单数加一。大多数情况下,这是因为扩展目标是IEnumerable,而不是IList。所以我认为你的方法很好。