从列表中删除类似的条目

时间:2015-05-20 01:16:50

标签: c# linq

我有一个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表达式)来执行此操作吗?

3 个答案:

答案 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。所以我认为你的方法很好。