3

我有两个具有相同长度的双值列表。

是否可以使用 select 语句遍历两个列表并返回同一位置的元素之间差异的平均值?

例子 : {1 2 3 4}

{1 1 1 1}

我想回来( (1 - 1) + (2 - 1) + (3 - 1) + (4 - 1) ) / 4 = 6 / 4 = 1.5

4

4 回答 4

3

尝试

listA.Zip(listB, (a, b) => a - b).Average();

如果没有 .NET 4.0 和 Zip,请尝试

listA.Select((n, index) => n - listB[index]).Average()
于 2012-05-02T15:03:39.747 回答
3
List<int> list1 = new List<int> { 1, 2, 3, 4 };
List<int> list2 = new List<int> { 1, 1, 1, 1 };

double result = list1.Zip(list2, (a, b) => a - b).Average();

当我运行它时,结果为 1.5。


仅仅因为我喜欢它并且它出现在其他评论之一中,这是我Zip可以在 C# 3.5 上运行的实现。

public static IEnumerable<T> Zip<T>(this IEnumerable<T> first
    , IEnumerable<T> second, Func<T, T, T> resultSelector)
{
    if (first == null)
        throw new ArgumentNullException("first");
    if (second == null)
        throw new ArgumentNullException("second");
    if (resultSelector == null)
        throw new ArgumentNullException("resultSelector");

    return ZipImpl(first, second, resultSelector);
}

public static IEnumerable<T> ZipImpl<T>(IEnumerable<T> first
    , IEnumerable<T> second, Func<T, T, T> resultSelector)
{
    IEnumerator<T> firstIterator = first.GetEnumerator();
    IEnumerator<T> secondIterator = second.GetEnumerator();
    while (firstIterator.MoveNext() && secondIterator.MoveNext())
    {
        yield return resultSelector(firstIterator.Current, secondIterator.Current);
    }
}
于 2012-05-02T15:04:00.577 回答
2

我不知道您是否对技术(Zip 方法)或结果感兴趣,但您将从以下代码中得到相同的结果:

var arr1 = new[] {1, 2, 3, 4};
var arr2 = new[] {1, 1, 1, 1};
var res = (arr1.Sum() - arr2.Sum())/(double) arr1.Length;
于 2012-05-02T15:10:47.580 回答
0

使用Enumerable.Range生成索引就可以了(如果你没有 .NET 4.0's Zip

var l1 = new List<int> { 1, 2, 3, 4 };
var l2 = new List<int> { 1, 1, 1, 1 };
double result = Enumerable.Range(0, l1.Count)
    .Select(i => l1[i] - l2[i])
    .Average();
于 2012-05-02T15:10:04.170 回答