gpt4 book ai didi

c# - 如何执行可以反转 key 的 LINQ GroupBy?

转载 作者:行者123 更新时间:2023-11-30 12:47:54 27 4
gpt4 key购买 nike

我正在尝试在 LINQ 中执行复杂的 GroupBy,但我在使用键选择器时遇到了问题。在下面的代码中,我可以在一个方向(通过 SellerID、BuyerID)按我的键进行分组,但实际上我也需要在相反方向(通过 SellerID、BuyerID 或 BuyerID、SellerID)按我的键进行分组。我这个查询的最终目的是当keys被反转的时候,我需要让Asset amount为负数。这将使我能够扣除双方存在的任何金额,然后我最终将只得到在该特定方面有金额的记录。

下面的代码应该可以解释它:

public class Record
{
public int RecordID;
public int SellerID;
public int BuyerID;
public List<Asset> Assets;
}

public class Asset
{
public int AssetID;
public decimal Amount;
}

var groups = new List<Record>
{
new Record { RecordID = 1, SellerID = 100, BuyerID = 200, Assets = new List<Asset> { new Asset { AssetID = 5, Amount = 10 }}},
new Record { RecordID = 2, SellerID = 100, BuyerID = 200, Assets = new List<Asset> { new Asset { AssetID = 5, Amount = 20 }}},
new Record { RecordID = 3, SellerID = 100, BuyerID = 200, Assets = new List<Asset> { new Asset { AssetID = 6, Amount = 60 }}},
new Record { RecordID = 4, SellerID = 200, BuyerID = 100, Assets = new List<Asset> { new Asset { AssetID = 5, Amount = 40 }}},
new Record { RecordID = 5, SellerID = 200, BuyerID = 100, Assets = new List<Asset> { new Asset { AssetID = 5, Amount = 50 }}},
new Record { RecordID = 6, SellerID = 200, BuyerID = 100, Assets = new List<Asset> { new Asset { AssetID = 6, Amount = 35 }}}
};

var result = groups.GroupBy(
r => new { r.SellerID, r.BuyerID },
r => r.Assets,
(r, assets) => new
{
r.SellerID,
r.BuyerID,
AssetSummation = assets.SelectMany(asset => asset).GroupBy(a => a.AssetID).Select(a2 => new { AssetID = a2.Key, Amount = a2.Sum(a3 => a3.Amount) })
});

我希望我的输出如下:

  • 记录 1
    • 卖家:100
    • 买家:200
    • Assets :
      • Assets
        • Assets ID:6
        • 数量:25
  • 记录 2
    • 卖家:200
    • 买家:100
    • Assets :
      • Assets ID:5
      • 数量:60

我想我有一个好的开始,但我不确定从这里到哪里去。我如何翻转 key 然后使金额为负数,以便我可以将它们相加?我认为,在我能够做到这一点之后,我可以过滤掉值为 0 的任何 Assets 行(意味着记录由逆向实现。

编辑#1:也许我正在尝试做的是将组变量连接到自身,以便对连接两侧的所有匹配记录求和。因此,我最终会将左侧的 SellerID 连接到右侧的 BuyerID,并将左侧的 BuyerID 连接到右侧的 SellerID。

最佳答案

这是返回您预期结果的查询:

var result = records
.SelectMany(r => new[] { r, new Record { // 1
SellerID = r.BuyerID,
BuyerID = r.SellerID,
Assets = r.Assets.Select(a => new Asset {
AssetID = a.AssetID,
Amount = -a.Amount
}).ToList() }})
.GroupBy(r => new { r.SellerID, r.BuyerID }) // 2
.Select(g => new { // 3
Seller = g.Key.SellerID,
Buyer = g.Key.BuyerID,
Assets = g.SelectMany(r => r.Assets)
.GroupBy(a => a.AssetID)
.Select(ag => new {
AssetID = ag.Key,
Amount = ag.Sum(a => a.Amount) })
.Where(x => x.Amount > 0) });

它是如何工作的?很简单:

  1. 对于每条记录,我选择两条记录 - 一条保持原样,另一条是买卖双方颠倒的(所有 Assets 的金额也是负数)。然后,我使用 SelectMany 将所有记录展平。
  2. 并按卖家和买家对其进行分组。
  3. 剩下的就是简单计算每组的 Assets 数额。

BTW 您可以在最后一个选择语句中创建您的 RecordAsset 对象,而不是返回匿名对象。

关于c# - 如何执行可以反转 key 的 LINQ GroupBy?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15484446/

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