gpt4 book ai didi

c# - 如何使用 C#/LINQ 计算加权平均值

转载 作者:行者123 更新时间:2023-11-30 16:37:53 25 4
gpt4 key购买 nike

这是处理库存数据;数据采用这种格式:

public class A
{
public int Price;
public int Available;
}

让我们以这个数据为例:

var items = new List<A>
{
new A { Price = 10, Available = 1000 },
new A { Price = 15, Available = 500 },
new A { Price = 20, Available = 2000 },
};

我的查询返回特定数量的平均价格,例如:

  • 如果我的请求量是 100,我的平均价格是 10

  • 如果我的请求量为 1200,我将以 10 的价格获取前 1000 个,然后以 15 的价格获取下 200 个等等

我已经在 C# 中实现了它,但我正在尝试寻找是否可以通过 LINQ 直接使用数据库迭代器来完成。

我得到的数据已经按价格排序,但我不知道如何在不迭代的情况下解决这个问题。


编辑:

这是代码:

public static double PriceAtVolume(IEnumerable<A> Data, long Volume)
{
var PriceSum = 0.0;
var VolumeSum = 0L;

foreach (var D in Data)
{
if (D.Volume < Volume)
{
PriceSum += D.Price * D.Volume;
VolumeSum += D.Volume;
Volume -= D.Volume;
}
else
{
PriceSum += D.Price * Volume;
VolumeSum += Volume;
Volume = 0;
}

if (Volume == 0) break;
}

return PriceSum / VolumeSum;
}

和测试代码:

var a = new List<A>
{
new A { Price = 10, Volume = 1000 },
new A { Price = 15, Volume = 500 },
new A { Price = 20, Volume = 2000 }
};

var P0 = PriceAtVolume(a, 100);
var P1 = PriceAtVolume(a, 1200);

澄清:

上面我说我想将它移到 LINQ 以使用数据库迭代器,所以我想避免扫描整个数据并在计算出答案时停止迭代。数据已在数据库中按价格排序。

最佳答案

这可能是您可以获得的最多的 Linqy。它使用 Aggregate 方法,特别是 Aggregate 的三个重载版本中最复杂的一个,它接受三个参数。第一个参数是种子,用清零的 ValueTuple<long, decimal> 初始化。 .第二个参数是累加器函数,具有将种子和当前元素组合成新种子的逻辑。第三个参数采用最终累加值并将它们转换到理想的平均值。

public static decimal PriceAtVolume(IEnumerable<A> data, long requestedVolume)
{
return data.Aggregate(
(Volume: 0L, Price: 0M), // Seed
(sum, item) => // Accumulator function
{
if (sum.Volume == requestedVolume)
return sum; // Goal reached, quick return

if (item.Available < requestedVolume - sum.Volume)
return // Consume all of it
(
sum.Volume + item.Available,
sum.Price + item.Price * item.Available
);

return // Consume part of it (and we are done)
(
requestedVolume,
sum.Price + item.Price * (requestedVolume - sum.Volume)
);
},
sum => sum.Volume == 0M ? 0M : sum.Price / sum.Volume // Result selector
);
}

更新:我将返回类型从 double 更改为十进制,因为 decimal is the preferred type for currency values .

顺便说一句,如果经常使用相同的数据调用此函数,并且数据列表很大,可以通过将累积的摘要存储在 List<(long, decimal)> 中来优化它。 , 并申请 BinarySearch 快速找到想要的条目。不过它变得很复杂,我不认为优化的先决条件会经常出现。

关于c# - 如何使用 C#/LINQ 计算加权平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56672645/

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