是否有可能,以及如何使用Lambda linq进行重构

时间:2018-08-29 03:51:56

标签: c# linq lambda refactoring

我正在尝试确定名称是否在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)的思考也将受到赞赏。

3 个答案:

答案 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();