我正在尝试搜索一组工作日,以确定该工作人员当天是否工作,并获得总计工作天数。下面的方法可以工作,但是效率很低,因为即使发现一个人一天都工作了,它仍然会在剩下的日子里继续寻找。如果我可以在满足内部条件(工作日)时以某种方式增加外部ForEach循环,那肯定会更快。 totalDaysWorked是我在下面的工作:
public class StationSupportRequest
{
public string RequestNum;
public string Status;
public string Prefix;
public string PlantLoc;
public DateTime Date;
public string Departmnt;
public DateTime Time;
public string StationID;
public string Fixture;
public string Supervisor;
public string PartNo;
public string SerialNum;
public string FailedStep;
public string Reason;
public string OtherReason;
public string Details;
public string Urgency;
public DateTime Date_1;
public DateTime Time_1;
public DateTime Date_2;
public DateTime Time_2;
public string ProblemFound;
public string SolutionCode;
public string Solution;
public double ServiceTechHrs;
public double ServiceEngHrs;
public string DocHistory;
public DateTime CloseDate;
public DateTime IniDate;
public DateTime IniTime;
public string MOT;
public string Initiator;
public string Notification;
public string ServiceTech;
public string ServiceEng;
public string SolutionCode_1;
public string Solution_1;
public string UpdatedBy;
public List<string> UpdatedByList;
public string Revisions;
public List<DateTime> RevisionsDateTime;
public List<WorkedDatapoint> WorkedDataPointsList;
}
public class WorkedDatapoint
{
public string AssignerName { get; set; }
public string AssigneeName { get; set; }
public DateTime Date { get; set; }
public bool AssignedToOther { get; set; }
}
var DateRange = SSRList.Where(y => y.IniDate >= IniDate && y.CloseDate < EndDate);
//DateRange = DateRange.Where(dr => dr.Fixture != null && dr.Fixture.Length == 6); //To get valid fixtures if pivoting on "Fixture"
var groupedData = DateRange.GroupBy(x => new { DS = x.ServiceTech }).Select(x =>
{
double totalSsrsWorkedOn = x.Select(y => y.RequestNum).Count();
IEnumerable<TimeSpan> hoursWorked = x.Select(y => y.CloseDate - y.IniDate.AddDays(GetWeekendDaysToSubtract(y.IniDate, y.CloseDate)));
var averageReactionTimeMinutes = x.Where(d => d.IniDate != null && d.Revisions != null)
.Average(d => ((DateTime.Parse(d.Revisions.Split(',')[0]) - (DateTime)d.IniDate)).Minutes);
double[] listOfMinutesOpenTime = x.Where(d => d.IniDate != null && d.Revisions != null)
.Select(d => Convert.ToDouble(((DateTime.Parse(d.Revisions.Split(',')[0]) - (DateTime)d.IniDate)).Minutes))
.ToArray();
double[] listOfDaysOpenTime = x.Where(d => d.IniDate != null && d.CloseDate != null)
.Select(d => ((DateTime)d.CloseDate - (DateTime)d.IniDate.AddDays(GetWeekendDaysToSubtract(d.IniDate, d.CloseDate))).TotalDays)
.ToArray();
string testtech = x.Select(y => y.ServiceTech).FirstOrDefault();
List<DateTime> totalDaysInDateRange = Enumerable.Range(0, 1 + EndDate.Subtract(IniDate).Days)
.Select(offset => IniDate.AddDays(offset)).ToList();
double totalHoursLogged = x.Sum(d => d.ServiceEngHrs) + x.Sum(d => d.ServiceTechHrs);
int assignedToOthersCount = x.SelectMany(y => y.WorkedDataPointsList)
.Where(z => z.AssignerName.Contains(testtech) && z.AssignedToOther == true)
.Count();
int brokenWiresFixed = x.Where(d => d.SolutionCode != null)
.Where(d => d.SolutionCode.Contains("A01 -") ||
d.SolutionCode.Contains("F01 -") ||
d.SolutionCode.Contains("S01 -")).Count();
int npfResults = x.Where(d => d.ProblemFound != null).Where(d => d.ProblemFound.Contains("NPF")).Count();
int totalDaysWorked = 0;
List<DateTime> workingDatesList = new List<DateTime>();
totalDaysInDateRange.ForEach((day) =>
{
x.Select(y => y.WorkedDataPointsList).ForEach((WorkedDataPoint) =>
{
IEnumerable<WorkedDatapoint> dateList = WorkedDataPoint
.Where(y => testtech == y.AssignerName)
.DistinctBy(z => z.Date.Date);
foreach ( WorkedDatapoint date in dateList)
{
if (x.Any(b => b.Date.Date.Date == date.Date.Date.Date))
{
workingDatesList.Add(date.Date.Date.Date);
break;
}
}
});
});
workingDatesList.Dump("WorkingDatesList");
totalDaysWorked = workingDatesList.DistinctBy(b => b.Date).Count();
/*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++;
}
}); TODO: Delete this once new is working*/
return new
{
//SSRs = x,
//Station = x.Select(d => d.StationID).FirstOrDefault(),
//Fixture = x.Select(d => d.Fixture).FirstOrDefault(),
//ProductTested = x.Select(d => d.Details).FirstOrDefault(),
TestTech = testtech,
//TestEng = x.Select(d => d.ServiceEng).Distinct().Where(d => d.Length > 0),
TotalSSRsWorkedOn = Math.Round(totalSsrsWorkedOn, 4),
TotalHoursLogged = Math.Round(totalHoursLogged, 4),
AssignedToOthersCount = assignedToOthersCount,
AssignedToOthersPercentage = 100 * Math.Round(assignedToOthersCount / (assignedToOthersCount + totalSsrsWorkedOn), 4),
//AverageReactionTimeMinutes = averageReactionTimeMinutes,
AverageTimeToCompleteHours = x.Where(y => y.CloseDate != null && y.Time_1 != null && y.Time_1 != DateTime.MinValue).Select(z => (z.CloseDate - z.Time_1).TotalHours).Average(),
//Close = x.Where(y => y.CloseDate != null && y.Time_1 != null).Select(z => (z.CloseDate)),
//Time = x.Where(y => y.CloseDate != null && y.Time_1 != null).Select(z => (z.Time_1)),
MedianDaysRequestOpen = Math.Round(GetMedian(listOfDaysOpenTime), 3),
DaysWorkedPerDateRange = totalDaysWorked,
AveSSRsClosedPerWorkedDay = Math.Round(totalSsrsWorkedOn / totalDaysWorked, 3),
AveHoursLoggedPerRequest = Math.Round((x.Select(y => y.ServiceTechHrs + y.ServiceEngHrs).Sum()) / totalSsrsWorkedOn, 3),
BrokenWiresFixed = brokenWiresFixed,
PercentageBrokenWires = 100 * Math.Round(brokenWiresFixed / totalSsrsWorkedOn, 4),
NPFResults = npfResults,
PercentageNPF = 100 * Math.Round(npfResults / totalSsrsWorkedOn, 4),
};
}).OrderByDescending(x => x.TotalSSRsWorkedOn)
.Dump("Summary");
return;
样本输出,并评估了重复的日期(workingDatesList):
8/1/2017 12:00:00 AM
8/1/2017 12:00:00 AM
8/1/2017 12:00:00 AM
2017年8月2日12:00:00 AM
答案 0 :(得分:0)
对您发布的代码的几点评论:
day
变量,因此只需完全删除该循环即可。x.Any(...)
上循环访问y
?这似乎有根本缺陷。我无法从您的问题陈述中识别出您的数据结构是什么,或者您实际上试图做什么。您的问题陈述当前的措辞为:
我正在搜索一组工作日,以确定某个工人当天是否工作,并获得总计工作天数。
似乎您正在接受名为testtech
(String
)和totalDaysInDateRange
(List<DateTime>
)的输入,然后想要在某个数据结构{{1 }}(我无法推断出这是什么)x
所在的位置。这种解释正确吗?
如果是这样,只需遍历String.equalsIgnoreCase(y.AssignerName, testtech) && totalDaysInDateRange.contains(y.Date)
数据结构中的所有条目,然后运行上述逻辑即可。如果这不能解决您的问题,请向我们提供有关数据结构x
的布局以及有关每个工作人员的信息实际上如何与该工作人员的其他数据相关联的更多信息。
开始编辑
好的,既然您已经提供了更多信息,我认为您想用以下内容替换x
语句:
totalDaysInDateRange.ForEach
更改实现后,只需删除x.Select(y => y.WorkedDataPointsList).ForEach((wdp) =>
{
if (testtech == wdp.AssignerName && IniDate.Date <= wdp.Date.Date
&& wdp.Date.Date <= EndDate.Date)
{
workingDatesList.Add(wdp.Date.Date);
}
});
。我还建议将totalDaysInDateRange
的类型更改为workingDatesList
,因为您似乎并不关心重复的日期。如果要按时间顺序打印日期,请确保将HashSet<DateTime>
转换为列表并在循环完成后对其进行排序。