我有一个具有此实现的对象列表:
class Locations
{
public string Origin { get; set; }
public string Dest { get; set; }
public int Total { get; set; }
}
我需要输出一个 CSV 格式的表格,其中起点为行,目的地为列,以及指定起点和终点相交的总数。我的列表中可能有任意数量的位置对象。
鉴于我的列表中有以下记录:
Origin=A
Dest=B
Total=10
Origin=B
Dest=A
Total=20
我的输出将如下所示(带有“-”字符意味着相同的出发地/目的地之间没有总计):
Origins/Destinations,A,B
A,-,10
B,20,-
到目前为止,我已经完成了以下工作:
1)遍历List输出Destinations。
2) 遍历List输出一个Origin。对于起点,遍历列表以查找与起点相关的每个目的地的总计。
3) 对下一个原点重复 #2。
我的结果不太好,因为行/列数据并不总是匹配。有没有更简单的解决方案?
最佳答案
更新
阅读您的更新后,似乎没有必要求和,因为只有一个具有给定 Origin
和 Destination
的对象。在这种情况下,您可以保留收集 地点
的代码,执行嵌套的 foreach
并简单地使用
var item = locations.FirstOrDefault(l => l.Origin == origin && l.Dest == dest);
var total = item == null ? 0 : item.Total;
原始答案
您可以通过以下方式获取所有位置的列表
var locations = new List<Locations>(); // assume it's populated
var places = locations.Select(l => l.Origin)
.Concat(locations.Select(l => l.Dest))
.Distinct()
.OrderBy(s => s); // why not sort it as well
此时,您可以简单地迭代行的 places
并为列执行另一次嵌套迭代:
foreach (var origin in places)
{
foreach (var dest in places)
{
var total = locations.Where(l => l.Origin == origin && l.Dest == dest)
.Sum(l => l.Total);
}
}
您可以立即看到如何轻松地使用此结构构建表。这种方法的主要缺点是它所做的工作比严格必要的多得多。理论上,我们当然可以对位置
进行一次迭代,边走边收集信息。可以将每对 Origin
和 Dest
的 Total
相加为
var totals = locations.GroupBy(l => new { l.Origin, l.Dest })
.ToDictionary(g => Tuple.Create(g.Key.Origin, g.Key.Dest),
g => g.Sum(r => r.Total));
此时我们可以从第一个解决方案中获取页面:
foreach (var origin in places)
{
foreach (var dest in places)
{
var total = totals[Tuple.Create(origin, dest)]; // almost too easy :)
}
}
关于c# - 将对象列表转换为表格结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10710044/