林克分组由和求和问题

本文关键字:求和 问题 林克 | 更新日期: 2023-09-27 18:28:58

我有以下实体:

带有订阅列表的帐户类:

public class Account
{
    /// <summary>
    /// Account ID
    /// </summary>
    public string ID { get; set; }
    /// <summary>
    /// A List with all subscriptions
    /// </summary>
    public IEnumerable<Subscription> Subscriptions { get; set; }
}

带有变体和附加组件列表的订阅类:

public class Subscription
{
    /// <summary>
    /// Subscription ID
    /// </summary>
    public string ID { get; set; }
    /// <summary>
    /// Quantity of the subscription.
    /// </summary>
    public int Quantity { get; set; }
    /// <summary>
    /// A list with all subscription add ons
    /// </summary>
    public IEnumerable<AddOn> AddOns { get; set; }
    /// <summary>
    /// A List with all subscription variations
    /// </summary>
    public IEnumerable<Variation> Variations { get; set; }
}

带有变体列表的附加类:

public class AddOn
{
    /// <summary>
    /// Gets or Sets add on id
    /// </summary>
    public string ID { get; set; }
    /// <summary>
    /// Quantity of the add on.
    /// </summary>
    public int Quantity { get; set; }
    /// <summary>
    /// A List with all add on variations
    /// </summary>
    public IEnumerable<Variation> Variations { get; set; }
}

以及变体类别:

public class Variation
{
    /// <summary>
    /// Variation ID
    /// </summary>
    public string ID { get; set; }
    /// <summary>
    /// offerUri
    /// </summary>
    public string Code { get; set; }
    /// <summary>
    /// Variation Value
    /// </summary>
    public string Value { get; set; }
    /// <summary>
    /// Variation Name
    /// </summary>
    public string Name { get; set; }
}

我想做的是用特定的代码对所有附加组件进行分组,并对数量求和。例如,我尝试过:

var groupAddOnsByCode = acc.Subscriptions.Select(s => s.AddOns.GroupBy(a => a.Variations.Select(v => v.Code).FirstOrDefault())).ToList();

这是一个正确的组外接程序,但我想要一个列表,按代码和每个代码的总数量列出每个订阅组的外接程序。

例如,如果订阅具有X个附加组件,并且每个附加组件的代码为1、2、。。。,X、 我想按代码和此代码的总数量对附加组件进行分组。如果我有以下结构,我预计结果会是这样的:

具有当前结构的伪代码(code指每个插件具有的Variation类):

Subscription {
 //a list with X number of add ons
 AddOn1 = { Variation = { Code = 1 }, Quantity = 2 },
 AddOn2 = { Variation = { Code = 2 }, Quantity = 3 },
 ...
 AddOnX = { Variation = { Code = X }, Quantity = 4 }
}

我的期望:

Subscription {
    AddOn1 { Variation = { Code = 1 }, Quantity = totalAmountOfQuantityForAddOnsWithCode = 1 },
    ...
    AddOnX { Variation = { Code = X }, Quantity = totalAmountOfQuantityForAddOnsWithCode = X },
}

您可以使用dotnetfidd测试伪数据。

很抱歉发了这么长的帖子,我会感谢你的帮助。还要记住,我的c#和Linq知识是有限的。

林克分组由和求和问题

如果我理解正确,以下内容可能会产生所需的结果

var result = acc.Subscriptions.Select(s => new
{
    Subscription = s,
    AddOns = s.AddOns.SelectMany(a => a.Variations, (a, v) => new { a, v })
        .GroupBy(e => e.v.Code, (key, elements) => new 
        { 
            Code = key,
            Quantity = elements.Sum(e => e.a.Quantity)
        }).ToList()
}).ToList();

虽然我不完全确定这是你想要的,但试试这个

var codes = addOns.SelectMany(a => a.Variations).Select(v => v.Code).Distinct();
var addOnsByCode = new List<AddOn>(); //your desired result
foreach (var code in codes)
{
    var addOnsWithThisCode = addOns.Where(a => a.Variations.Any(v => v.Code == code));
    addOnsByCode.Add(new AddOn{
        Variations = new List<Variation> { new Variation { Code = code } },
        Quantity = addOnsWithThisCode.Sum(a => a.Quantity),
        ID = string.Join("_", addOnsWithThisCode.Select(a => a.ID)) //not required>
    });
}

其中addOnsList<AddOn>,例如

var addOns = new List<AddOn> {
    new AddOn { 
        ID = "1", 
        Quantity = 5, 
        Variations = new List<Variation> 
        {
            new Variation { Code = "A" },
            new Variation { Code = "B" }
        } 
    },
    new AddOn { 
        ID = "2", 
        Quantity = 7, 
        Variations = new List<Variation> 
        {
            new Variation { Code = "B" },
            new Variation { Code = "C" }
        } 
    },
    new AddOn { 
        ID = "3", 
        Quantity = 9, 
        Variations = new List<Variation> 
        {
            new Variation { Code = "D" },
            new Variation { Code = "A" }
        } 
    },
};

如果我正确理解你的问题,我认为下面的方法会有所帮助。我在Subscription类中添加了一个方法,通过其变体代码对其加载项进行分组,然后对各种代码的数量求和。我的代码的关键是使用SelectMany将具有多个变体的单个Add-On分解为成对的code和Quantity的单独元素。然后可以对分解的元素进行分组。

public Dictionary<string, int> GetAddonGroups()
{
    //spreading out each Add-on into multiple elements, each with a Code and quantity
    var addOnVariationsWithQuantity = this.AddOns
        .SelectMany(ad =>  ad.Variations
                    .Select(v => new {Code = v.Code, Quantity = ad.Quantity}));
    //group by Code and Sum the quantity
    var addOnGroups = addOnVariationsWithQuantity
                        .GroupBy(v => v.Code)
                        .ToDictionary(grp => grp.Key, 
                                      grp => grp.Sum( el => el.Quantity));
    return addOnGroups;
}

分叉Fiddle