c# Match between two lists, then add up time in between the two lists

隐身守侯 提交于 2021-02-08 10:46:29

问题


I have two lists and a class

public class CommonLog
{
    public string Break { get; set; }
    public string Cart { get; set; }
    public string Length { get; set; }
}

This is list one

commonlog.Add(new CommonLog { Break = breakTimeVar, Cart = cartVar,
    Length = lengthHours });

and one like this list 2

commonlog2.Add(new CommonLog { Break = breakTimeVar2, Cart = cartVar2,
    Length = lengthHours2 });

The two pieces of information I need to match are as follows

List 1 contains this

0016 009130 00:01:30

List 2 Contains this

0016 0066486 00:00:30

0016 0050093 00:00:30

0016 0063791 00:00:30

I need to match up the first number 0016 between the two lists, and then add up the last numbers 00:00:30 (3 x 30 seconds) from list 2 and compare that total time against list 1 total time, and then make a decision based on if the total of the last numbers (time) from list 2 equal list 1

How would I achieve that?


回答1:


Here it is a LINQ solution which aggregates your List 2 entries in a similar (but more compact) way of Romoku answer:

var groupedLogs = commonlog2
    .GroupBy(c => c.Break, c => TimeSpan.Parse(c.Length))
    // group logs by Break, and get the TimeSpan representation of Length
    // for each entry of the group
    .ToDictionary(g => g.Key, g => g.Aggregate(TimeSpan.Zero, (s, c) => s + c));
    // create a dictionary and aggregate each log group into sums of TimeSpans

Then you may iterate through each item of commonlog and compare the results:

foreach(var log in commonlog)
{
    TimeSpan sum;
    groupedLogs.TryGetValue(log.Break, out sum);
    if(sum == TimeSpan.Parse(log.Length))
    {
        // do something
    }
}

Or a one liner way to get only matching entries from commonlog (using C# 7 features):

var matching = commonlog.Where(
    l => groupedLogs.TryGetValue(l.Break, out TimeSpan v)
         && TimeSpan.Parse(l.Length) == v);



回答2:


You can group the individual breaks using GroupBy then loop through the aggregate breaks to find matches.

To sum the individual breaks there is Aggregate.

I recommend using TimeSpan instead of string for the Length.

Data

var totalBreaks = new List<CommonLog>
{
    new CommonLog
    {
        Break = "0016",
        Cart = "009130",
        Length = "00:01:30"
    }
};

var individualBreaks = new List<CommonLog>
{
    new CommonLog
    {
        Break = "0016",
        Cart = "0066486",
        Length = "00:00:30"
    },
    new CommonLog
    {
        Break = "0016",
        Cart = "0050093",
        Length = "00:00:30"
    },
    new CommonLog
    {
        Break = "0016",
        Cart = "0063791",
        Length = "00:00:30"
    }
};

Logic

//Group the individual breaks by their Break
var breakGroups = individualBreaks.GroupBy(x => x.Break);

// Loop through the aggregates
foreach (var totalBreak in totalBreaks)
{
    // Match the aggregate to the individual
    // The Key is the Break for all individual breaks in the group
    var breaks = breakGroups.FirstOrDefault(x => x.Key == totalBreak.Break);

    // Do we have a match?
    if (breaks == null)
    {
        continue;
    }

    var breakLength = TimeSpan.Parse(totalBreak.Length);
    // Add up the individual breaks with Aggregate
    var breakTotal =
        breaks
            .Aggregate(
                TimeSpan.Zero,  // Initial break is 00:00:00
                (time, b) =>    // Add each break to the initial
                    time.Add(TimeSpan.Parse(b.Length)));

    // Does the break length match the total number of breaks?
    if (breakLength == breakTotal)
    {
    }
}


来源:https://stackoverflow.com/questions/46224453/c-sharp-match-between-two-lists-then-add-up-time-in-between-the-two-lists

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!