LINQ中的条件分组

本文关键字:条件 LINQ | 更新日期: 2023-09-27 18:05:37

我正在尝试做非常相似的linq语句,但有条件的条件,它们略有不同。现在我只是重复整个声明,稍加修改,但这应该可能更简洁。我挣扎的是在语句中做条件分组和条件选择。我的长版本是:

class data
{
    public string year;
    public string quarter;
    public string month;
    public string week;
    public string tariff;
    public double volume;
    public double price;
}
class results
{
    public string product_code;
    public string tariff;
    public double volume;
    public double price;
}
class Program
{
    public static List<results> aggregationfunction(List<data> inputdata, string tarifftype, string timecategory)
    {
        List<results> returndata = new List<results>();
        if (tarifftype.Equals("daynight") & timecategory.Equals("yearly"))
        {
            returndata = inputdata.GroupBy(a => new { a.tariff, a.year })
                                  .Select(g => new results { product_code = g.Select(a => a.year).First(), tariff = g.Select(a => a.tariff).First(), volume = g.Sum(a => a.volume), price = g.Average(a => a.price) })
                                      .ToList();
        }
        else if (tarifftype.Equals("allday") & timecategory.Equals("yearly"))
        {
            returndata = inputdata.GroupBy(a => new { a.year })
                                  .Select(g => new results { product_code = g.Select(a => a.year).First(), tariff = "allday", volume = g.Sum(a => a.volume), price = g.Average(a => a.price) })
                                  .ToList();
        }
        else if (tarifftype.Equals("daynight") & timecategory.Equals("quarterly"))
        {
            returndata = = inputdata.GroupBy(a => new { a.tariff, a.year, a.quarter })
                                    .Select(g => new results { product_code = g.Select(a => a.year).First() + "_" + g.Select(a => a.quarter).First(), tariff = g.Select(a => a.tariff).First(), volume = g.Sum(a => a.volume), price = g.Average(a => a.price) })
                                    .ToList();
        }
        else if (tarifftype.Equals("allday") & timecategory.Equals("quarterly"))
        {
            returndata = inputdata.GroupBy(a => new { a.year, a.quarter })
                                  .Select(g => new results { product_code = g.Select(a => a.year).First() + "_" + g.Select(a => a.quarter).First(), tariff = "allday", volume = g.Sum(a => a.volume), price = g.Average(a => a.price) })
                                  .ToList();
        } 
        return returndata;
    }
}

任何提示将不胜感激。正如你所看到的,关税和产品代码的分组和分配是不同的,但这并不意味着我需要重复所有的内容,不是吗?

LINQ中的条件分组

短代码:

return inputdata
    .GroupBy(a => new
    {
        a.year,
        quarter = timecategory == "quarterly" ? a.quarter : string.Empty,
        tariff = tarifftype == "daynight" ? a.tariff : "allday"
    })
    .Select(g => new results
    {
        product_code = g.Key.year + (string.IsNullOrEmpty(g.Key.quarter) ? "" : "_" + g.Key.quarter),
        tariff = g.Key.tariff,
        volume = g.Sum(a => a.volume),
        price = g.Average(a => a.price)
    })
    .ToList();

inputdata.GroupBy返回的IGrouping<TKey, data>项(其中datainputdata的元素类型)将始终实现IEnumerable<data>,而不管匿名密钥类型(可能是{year}或{tariff, year}等)。因此,所有的GroupBy值都可以概括为IEnumerable<IEnumerable<data>>,然后您可以将其分解为两个步骤:

IEnumerable<IEnumerable<data>> groups;
if (condition) {
    groups = inputdata.GroupBy(a => new { a.year });
} else if (condition) {
    groups = inputdata.GroupBy(a => new { a.tariff, a.year });
} else {
    groups = inputdata.GroupBy(a => new { a.year, a.quarter });
}
returndata = groups.Select(...)

条件选择应该更容易实现,因为你可以只使用内联条件操作符,或者将选择器函数扩展为多行块,例如:

.Select(g => {
    var product_code = ...;
    if (condition) {
        product_code += "_" + ...;
    }
    return new results { product_code = product_code, ... };
})