我试图做非常相似的linq语句,但条件是条件略有不同。现在我只是用小修改重复整个陈述,但这应该更简洁。我所挣扎的是在语句中进行条件groupby和条件选择。我的长版本是:
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;
}
}
任何指针都将不胜感激。正如你所看到的那样,关税和产品代码的分组和分配有所不同,但这并不意味着我需要重复一遍,是吗?
答案 0 :(得分:6)
更短的代码:
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();
答案 1 :(得分:1)
inputdata.GroupBy
返回的IGrouping<TKey, data>
项(其中data
是inputdata
的元素类型)将始终实现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(...)
条件选择应该更容易实现,因为您可以只使用conditional operators内联,或将选择器函数扩展为多行块,例如:
.Select(g => {
var product_code = ...;
if (condition) {
product_code += "_" + ...;
}
return new results { product_code = product_code, ... };
})