CATEGORY MILES
Business 5.1
Business 4.6
Business 3.9
Personal 8.5
Business 3.7
Personal 6.2
Personal 11
这是摘录自excel表格
因此,您有一个CSV格式的文本文件,您需要读取它,将其转换为[Category,Miles]的组合,并且您希望每个Category"%英里数";,不管是什么。
Category Miles
X 1
X 4
X 2
Y 3
我认为你想要:;类别X具有70%的里程,类别Y也具有30%的里程";。
要解决这个问题,最好把你的问题切成小块。
- 给定一个字符串fileName,将文件读取为文本
- 给定CSV格式的字符串,将其转换为BusinessMiles类的序列
- 给定BusinessMiles的序列,将其转换为"%"英里数";,根据上述定义
将问题分割成更小的部分有几个优点:
- 每件作品的功能都会更容易理解
- 更容易进行单元测试
- 更容易更改,例如,如果您不是从CSV文件而是从数据库读取,或者如果您不是从不CSV字符串而是从XML或JSON文件读取
- 最重要的是:你将能够将这些片段重新用于其他任务,比如:";我的几行是关于商业的">
可重用性得到了最清楚的证明,因为其中几个部分已经存在,并且可以自由使用:读取文件并将文件转换为CSV。
为此,请考虑使用Nuget Package CSV帮助程序。易于使用,用途广泛,因此是最常用的CSV包之一。
因此,假设您有读取CSV文件并将其转换为BusinessMiles 序列的过程
enum Category
{
Business,
Personal,
}
class BusinessMile // TODO: invent proper name
{
public Category Category {get; set;}
public Decimal Miles {get; set;}
}
通过使用枚举,您可以确定在阅读CSV后不会有任何不正确的类别。为将来的版本添加新的类别将很容易。如果你在编译时不知道哪些类别是允许的,可以考虑使用字符串。这有可能导致有人出现键入错误,从而导致一个全新的类别,而没有人注意到";人员;而不是";"个人";
IEnumerable<BusinessMile> ReadBusinessMiles(string csvText)
{
// use CSVHelper to convert the csvText to the sequence
}
IEnumerable<BusinessMile> ReadBusineMilesFile(string fileName)
{
// either use CSVHelper, or read the file and call the other method
}
在这之后,你的问题将很容易:
string fileName = ...
IEnumerable<BusinessMile> businessMiles = ReadBusinesMilesFile(fileName);
制作具有相同类别的BusinessMiles群组:
var categoryGroups = businessMiles.GroupBy(
businessMile => businessMile.Category,
// parameter resultSelector: for every Category, and all BusinessMiles
// that have this Category to make one new
(category, businessMilesInThisCategory) => new
{
Category = category,
TotalMiles = businesMilesInThisCategory
.Select(businessMile => businessMile.Miles)
.Sum(),
});
所以现在你有了:
Category TotalMiles
X 7
Y 3
如果你真的想知道百分比,你需要得到所有类别的所有里程的总和(=6(,并用总里程除以这个
var totalMiles = categorieGroups.Select(group => group.TotalMiles).Sum();
var result = categoryGroups.Select(group => new
{
Category = group.Category,
TotalMilesPercentage = 100.0M * group.TotalMiles / totalMiles,
})
在我对BusinessMiles的定义中,Miles是十进制数。如果您的里程数是整数,请小心转换。