gpt4 book ai didi

c# - 在 C# 中,将数组中的项合并为 "single larger item"的一部分的最优雅方法是什么?

转载 作者:太空宇宙 更新时间:2023-11-03 23:23:23 28 4
gpt4 key购买 nike

我有一个 C# 应用程序,我正在从跟踪人们请求的外部跟踪系统中提取数据,并将它们存储在我的数据库中。所以像这样:

public class Request
{
public DateTime Start {get;set;}
public DateTime End {get;set;}
public int PersonId {get;set;}
}

IEnumerable<Request> requests = GetExternalRequests();

GetExternalRequests() 的细节与问题无关。

问题是该服务将事情分解为每一天向我发送一个请求(即使该请求是多天的请求)

例如,如果一个人提出一个整周(周一到周五)的请求,我在数组中得到 5 个不同的项目(每个都有一个日期),我想将它们“合并”成一个请求开始 = 星期一和结束 = 星期五,以避免将 5 条不同的记录保存到我的数据库中。

到目前为止,我觉得这是一个非常不优雅的解决方案,我循环遍历所有请求并将结果放入字典中,然后运行下面的代码

IEnumerable<Request> requests = GetExternalRequests();

IEnumerable<Request> previousRequests = GetAllPreviousRequests();

Dictionary<string, Request> cachedDictionary = CacheAllRequestsByDateandPersonId(requests, previousRequests)

var groupedByPerson = requests.GroupBy(r=>r.PersonId);
foreach (var group in groupedByPerson)
{
foreach (Request request in group.OrderBy(r=>r.StartDate)
{
var offSet = 1;
if (request.StartDate.DayOfWeek == DayOfWeek.Friday)
{
offSet = 3;
}
if (cachedDictionary.ContainsKey(request.PersonId + request.StartDate.AddDays(offset))
{
//delete the request from the list and change the start date of the next request to the start date of this request.
}
}
}

所以我想得到一些建议,看看是否有更优雅的方式来“合并”这些结果。

增加一些清晰度(基于下面的一些评论)

  • 请求不能重叠(想想休假请求)
  • 如果我在周一已经收到了之前的请求,而在周二又收到了一个新请求,那么我也想合并这些请求

最佳答案

假设您的 GetExternalRequests 返回一些类似的种子数据

private static IEnumerable<Request> GetExternalRequests()
{
yield return new Request(new DateTime(2015, 1, 4), new DateTime(2015, 1, 4), 1);
yield return new Request(new DateTime(2015, 1, 5), new DateTime(2015, 1, 5), 1);
yield return new Request(new DateTime(2015, 1, 6), new DateTime(2015, 1, 6), 1);
yield return new Request(new DateTime(2015, 1, 7), new DateTime(2015, 1, 7), 1);
yield return new Request(new DateTime(2015, 1, 8), new DateTime(2015, 1, 8), 1);

yield return new Request(new DateTime(2015, 1, 11), new DateTime(2015, 1, 11), 1);
yield return new Request(new DateTime(2015, 1, 15), new DateTime(2015, 1, 15), 1);

yield return new Request(new DateTime(2015, 1, 19), new DateTime(2015, 1, 19), 1);

yield return new Request(new DateTime(2015, 1, 26), new DateTime(2015, 1, 26), 1);

yield return new Request(new DateTime(2015, 1, 4), new DateTime(2015, 1, 4), 2);
yield return new Request(new DateTime(2015, 1, 7), new DateTime(2015, 1, 7), 2);
}

然后你可以使用GroupBy合并你的数据,然后Aggregate合并连续的天数

请看下面的代码:

private static IList<Request> MergeRequests(IEnumerable<Request> requests)
{
return requests.GroupBy(r => r.PersonId)
.Aggregate(new Stack<Request>(), (list, grouping) =>
{
foreach (var request in grouping.OrderBy(r => r.StartDate))
{
var peek = list.Any() ? list.Peek() : null;
if (peek?.EndDate.Date.Day + 1 == request.StartDate.Date.Day)
peek.EndDate = request.EndDate;
else
list.Push(request);
}
return list;
})
.OrderBy(x => x.PersonId).ThenBy(x => x.StartDate)
.ToList();
}

那么让我们测试一下这个解决方案

public static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
IEnumerable<Request> requests = GetExternalRequests();

var requestsMerge = MergeRequests(requests);


foreach (var request in requestsMerge)
Console.WriteLine($"Person Id: {request.PersonId} - StartDate: {request.StartDate} - EndDate: {request.EndDate}");
}

输出数据是:

Person Id: 1 - StartDate: 1/4/2015 12:00:00 AM - EndDate: 1/8/2015 12:00:00 AM

Person Id: 1 - StartDate: 1/11/2015 12:00:00 AM - EndDate: 1/12/2015 12:00:00 AM

Person Id: 1 - StartDate: 1/19/2015 12:00:00 AM - EndDate: 1/19/2015 12:00:00 AM

Person Id: 1 - StartDate: 1/26/2015 12:00:00 AM - EndDate: 1/26/2015 12:00:00 AM

Person Id: 2 - StartDate: 1/4/2015 12:00:00 AM - EndDate: 1/4/2015 12:00:00 AM

Person Id: 2 - StartDate: 1/7/2015 12:00:00 AM - EndDate: 1/7/2015 12:00:00 AM

关于c# - 在 C# 中,将数组中的项合并为 "single larger item"的一部分的最优雅方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34601819/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com