gpt4 book ai didi

arrays - LINQ - 根据数组 B 的值从数组 A 中选择元素

转载 作者:行者123 更新时间:2023-12-02 22:42:04 27 4
gpt4 key购买 nike

假设我们有两个数组:

DateTime[] wDates = new DateTime[20000];
double[] wValues = new double[20000];

这两个数组都是按顺序排列的,即给定一个 int i,wValues[i] 是日期 wDates[i]。

假设我们需要获得 wValues 的平均值,其中日期的月份是一月

使用标准循环,这将是:

double wAvg = 0.0;
int wDataCount = 0;
for (int i=0; i < 20000; i++)
if (wDates[i].Month == 1)
{
wAvg += wValues[i];
wDataCount++;
}

if (wDataCount > 0)
wAvg /= wDataCount;

我想知道如何在 LINQ 中执行此操作?我可以创建一个包含两个值的结构/类 DateDouble,然后执行类似的操作:

List<DateDouble> wListData = new List<DateDouble>();
Add the items...
double wAvg = (from d in wListData
where d.Date.Month == 1
select d.Value).Average();

但是如果每天创建数千万次,创建数千个 DateDouble 对象将是一个很大的内存开销。临时对象也会发生同样的情况,尝试使用“索引”并在数组上加入索引会产生糟糕的性能。

在 LINQ 中是否有更好的方法来实现这一点?

谢谢,毫米

最佳答案

好吧,您可以使用 Zip 运算符使事情变得更简单:

var average = wDates.Zip(wValues, (date, value) => new { date, value })
.Where(pair => pair.date.Month == 1)
.Average(pair => pair.value);

这仍然会为每对创建一个匿名类型的实例,但我个人会放手并衡量性能,然后再假设它会太昂贵。请注意,这将以流方式运行 - 因此尽管它会产生大量垃圾,但任何时候所需的总内存很小。

您可以通过创建自己的对 struct 来提高效率...这将避免创建额外的对象,但会更麻烦一些。不过,还不错:

// The normal Tuple types are classes.
public struct TupleValue<T1, T2>
{
private readonly T1 item1;
private readonly T2 item2;

public T1 Item1 { get { return item1; } }
public T2 Item2 { get { return item2; } }

public TupleValue(T1 item1, T2 item2)
{
this.item1 = item1;
this.item2 = item2;
}
}

var average = wDates.Zip(wValues, (date, value) =>
new TupleValue<DateTime, double>(date, value))
.Where(pair => pair.Item1.Month == 1)
.Average(pair => pair.Item2);

我只会在证明第一种方法代价高昂之后才这样做。

关于arrays - LINQ - 根据数组 B 的值从数组 A 中选择元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10639314/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com