我正在尝试确定名称是否在WorkedDataPoint列表中并且落入totalDaysInDateRange中的任意几天的方法。基本前提是,如果这两个日期匹配,则该人当天就工作了-我正在尝试计算“工作”天数。每个用户每天可能还会有一个以上的条目,而我们每天只能计算一个条目,因此“ morelinq”中的DistinctBy似乎是一个不错的选择...
我在这里拥有的应该可以正常工作,编译器在工作,所以不能肯定地说。但是我该如何使用linq lambda表达式来使其更简洁-尤其是foreach循环,该应用程序中的lambda可以以某种方式实现吗?
public class WorkedDatapoint
{
public string AssignerName { get; set; }
public DateTime Date { get; set; }
public bool AssignedToOther { get; set; }
}
List<DateTime> totalDaysInDateRange
List<WorkedDataPoint> AssignersList
testtech = "Bobby"
//The two lists are loaded here
int totalDaysWorked = 0;
foreach (var day in totalDaysInDateRange)
{
if (AssignersList.Where(d => testtech.Contains(d.AssignerName)).DistinctBy(d => d.Date.Date).Any(d => d.Date.Date == day.Date)
{
totalDaysWorked++;
}
}
编辑:我想我明白了,但是明天不能测试。有什么方法可以内联声明该变量TotalDaysWorked还是要求太多?
int totalDaysWorked = 0;
totalDaysInDateRange.ForEach((day) =>
{
if (AssignersList
.Where(d => testtech.Contains(d.AssignerName))
.DistinctBy(d => d.Date.Date)
.Any(d => d.Date.Date == day.Date))
{ totalDaysWorked++; }});
此方法“压缩”了数千条记录,因此,对于速度优化(大量的RAM和Intel-I7)的思考也将受到赞赏。
答案 0 :(得分:1)
可以执行以下操作:
int totalDaysWorked = totalDaysInDateRange.Intersect(AssignersList.Select(b => b.Date)).Count();
除了内部使用Set之外:
int count = totalDaysInDateRange.Count() - totalDaysInDateRange.Except(AssignersList.Select(b => b.Date)).Count();
警告: 对于大量用户,linq的运行速度非常慢,因此应予以禁止。有关here的更多信息:
答案 1 :(得分:0)
您可以针对以下问题编写linq查询:-
var AssignerDaysCount = assignerList.Where(filter =>
totalDaysInDateRange.Contains(filter.Date.Date))
.GroupBy(item => item.AssignerName)
.Select(lst => new { AssignerName = lst.Key, DaysCount = lst.Select(cnt => cnt.Date).Distinct().Count() })
.ToList();
答案 2 :(得分:0)
我建议在Date上加入totalDaysInDateRange和AssignersList。然后按AssignerName和日期分组。您将获得日期
var jointList = totalDaysInDateRange.Join(
AssignersList,
p => p,
c => c.Date,
(p, c) => new { c.AssignerName, c.Date }
).Distinct().GroupBy(x => x.AssignerName).Select(group =>
new {
AssignerName = group.Key,
Count = group.Count()
}).ToList();