LINQ C#将日期划分为句点

时间:2019-04-12 07:25:03

标签: linq

我有一个数据表,其中包含三列(名称和日期)

Names    Dates              amount
----------------------------------

John     01/01/2019         5
John     02/01/2019         10
John     04/01/2019         5
John     05/01/2019         4
Adam     01/01/2019         5
Adam     03/01/2019         5
Adam     04/01/2019         5

我需要检查错过的日子并安排时间

我希望输出类似

Names        Fr              To           amount
John     01/01/2019      02/01/2019         15
John     04/01/2019      05/01/2019          9
Adam     01/01/2019      01/01/2019          5
Adam     03/01/2019      04/01/2019         10

1 个答案:

答案 0 :(得分:0)

如果将问题分为多个子部分,那么它将变得更加简单。

  
      
  1. 从数据表的条目中进行配对。
  2.   
  3. 现在基于“名称”进行分组。
  4.   
  5. 在此组上,检查哪个组的时差为1个月。
  6.   
  7. 使用foreach循环对这些组进行投影。
  8.   

现在输入代码,

public static class Program
{

    static int CountNumberOfMonths(DateTime date1, DateTime date2) => (date2.Month - date1.Month) + 12 * (date2.Year - date1.Year);

    static void Main(string[] args)
    {

        DataTable table = new DataTable();
        table.Columns.Add("Name", typeof(string));
        table.Columns.Add("Dates", typeof(DateTime));
        table.Columns.Add("Amount", typeof(int));

        table.Rows.Add("John", new DateTime(2019, 1, 1), 5);
        table.Rows.Add("John", new DateTime(2019, 2, 1), 10);
        table.Rows.Add("John", new DateTime(2019, 4, 1), 5);
        table.Rows.Add("John", new DateTime(2019, 5, 1), 4);
        table.Rows.Add("Adam", new DateTime(2019, 1, 1), 5);
        table.Rows.Add("Adam", new DateTime(2019, 3, 1), 5);
        table.Rows.Add("Adam", new DateTime(2019, 4, 1), 5);

        var enumeratedDatatable = table.AsEnumerable();

        var filteredData = enumeratedDatatable
             .Zip(enumeratedDatatable.Skip(1), Tuple.Create)
             .GroupBy(x => x.Item1.Field<string>("Name"))
             .Select(x => x.Where(y =>
             {
                 int numMonths = CountNumberOfMonths(y.Item1.Field<DateTime>("Dates"), y.Item2.Field<DateTime>("Dates"));
                 return numMonths > 0 && numMonths == 1;
             }));


        DataTable result = new DataTable();
        result.Columns.Add("Name", typeof(string));
        result.Columns.Add("From", typeof(DateTime));
        result.Columns.Add("Sum", typeof(DateTime));
        result.Columns.Add("Amount", typeof(int));

        foreach (var item in filteredData)
        {
            string name = item.ElementAt(0).Item1.Field<string>("Name");
            foreach (var innerItem in item)
            {
                int sumAmount = innerItem.Item1.Field<int>("Amount") + innerItem.Item2.Field<int>("Amount");
                DateTime from = innerItem.Item1.Field<DateTime>("Dates");
                DateTime to = innerItem.Item2.Field<DateTime>("Dates");
                result.Rows.Add(name, from, to, sumAmount);
            }
        }

        // Printing the results to standard output
        foreach (DataRow row in result.Rows)
        {
            string rowItem = string.Join("\t", row.ItemArray);
            Console.WriteLine(rowItem);
        }
    }
}

输出:

John    01/01/2019 00:00:00     02/01/2019 00:00:00     15
John    04/01/2019 00:00:00     05/01/2019 00:00:00     9
Adam    03/01/2019 00:00:00     04/01/2019 00:00:00     10