我有以下代码:
public class Alert
{
public string Alias { get; set; }
public int ServiceHours { get; set; }
public int TotalHoursDone { get; set; }
public int UserId { get; set; }
public int VehicleId { get; set; }
}
private static readonly List<Alert> AlertsToDo = new List<Alert>();
public void SomeFunction() {
// creates a dictionary of user ids as the key with their alerts
// (sorted by alias) as the value.
// Just one loop needed and no awkward state logic.
var alertsGrouped = AlertsToDo.Select(a => a.UserId)
.Distinct()
.ToDictionary(userId => userId,
userId => AlertsToDo.Where(a => a.UserId == userId)
.OrderBy(a => a.Alias)
.ToList());
}
所以,我有一个Alert对象列表。我的LINQ查询输出一个字典,其中的键是UserId,其值是按Alias排序的UserId的警报列表。
我很满意这个查询的独创性,但我想知道是否有更简单的方法吗?具体来说,我必须为每个键使用第二个查询来创建值List。纯粹出于兴趣,因为这对于手头的工作来说足够快。
答案 0 :(得分:3)
使用Enumerable.GroupBy
方法可以提高可读性。对于少量数据,您很可能看不到差异,而大量数据会改变性能。您的查询首先获取不同的值,然后过滤UserId
上的项目。分组预先削减了这些步骤。要确定你需要描述一下。
以下是使用分组的查询:
var query = AlertsToDo.GroupBy(a => a.UserId)
.ToDictionary(g => g.Key,
g => g.OrderBy(a => a.Alias).ToList());
答案 1 :(得分:0)
对于延迟感到抱歉,但正如这里承诺的那样是一些测试结果。
我测试过的代码:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class Alert
{
public string Alias { get; set; }
public int ServiceHours { get; set; }
public int TotalHoursDone { get; set; }
public int UserId { get; set; }
public int VehicleId { get; set; }
}
private static readonly List<Alert> AlertsToDo = new List<Alert>();
private void button1_Click(object sender, EventArgs e)
{
var rng = new Random();
var watch = new System.Diagnostics.Stopwatch();
watch.Start();
for (int i = 0; i < 1000000; i++)
{
int random = rng.Next();
AlertsToDo.Add(new Alert
{
Alias = random.ToString(),
UserId = random
});
}
Console.WriteLine(@"Random generation: {0}", watch.ElapsedMilliseconds);
watch = new System.Diagnostics.Stopwatch();
watch.Start();
var alertsGrouped = AlertsToDo.Select(a => a.UserId)
.Distinct()
.ToDictionary(userId => userId,
userId => AlertsToDo.Where(a => a.UserId == userId)
.OrderBy(a => a.Alias)
.ToList());
watch.Stop();
Console.WriteLine(@"Mine: {0}", watch.ElapsedMilliseconds);
Console.WriteLine(alertsGrouped.Count);
watch = new System.Diagnostics.Stopwatch();
watch.Start();
alertsGrouped = AlertsToDo.GroupBy(a => a.UserId)
.ToDictionary(g => g.Key,
g => g.OrderBy(a => a.Alias).ToList());
watch.Stop();
Console.WriteLine(@"Ahmad's: {0}", watch.ElapsedMilliseconds);
Console.WriteLine(alertsGrouped.Count);
}
}
输出:
随机生成:769
我的:32164861(超过8小时)
999798
艾哈迈德:4133999798
不出所料,GroupBy更快,因为我的版本执行子查询,但只是看看有多快!
所以胜利者是:艾哈迈德,显然。