C#:修改列表

时间:2016-08-24 11:22:26

标签: c#

我有一张桌子(日期是mm / dd / yyyy格式):

FromID  ToID    FromDate    ToDate          
S1       S2     1/1/2016    1/15/2016
S2       S3     2/1/2016    3/14/2016
S1       S2     1/5/2016    1/20/2016
S2       S3     1/25/2016   2/25/2016
S1       S2     1/21/2016   1/25/2016

我需要组合行,以便重复fromId和ToId的重叠日期。例如,对于此表,输出应为:

FromID  ToID    FromDate    ToDate          
S1       S2     1/1/2016    1/25/2016
S2       S3     1/25/2016   3/14/2016

我已尝试使用以下C#代码来完成它,但它无法正常工作。

 public class MergeLists
  {

    static void Main(String[] args) {

        List<ItemDetails> theTempList = new List<ItemDetails>();
        List<ItemDetails> theOriList = new List<ItemDetails>();
        DateTime minDate = new DateTime(2016, 1, 1);
        DateTime maxDate = new DateTime(2016, 1, 1);
        int count;

        theOriList.Add(new ItemDetails("S1","S2", new DateTime(2016,1,1), new DateTime(2016,1,15)));
        theOriList.Add(new ItemDetails("S2", "S3", new DateTime(2016, 2, 1), new DateTime(2016, 2, 14)));
        theOriList.Add(new ItemDetails("S1", "S2", new DateTime(2016, 1, 5), new DateTime(2016, 1, 20)));
        theOriList.Add(new ItemDetails("S2", "S3", new DateTime(2016, 1, 25), new DateTime(2016, 2, 25)));
        theOriList.Add(new ItemDetails("S1", "S2", new DateTime(2016, 1, 21), new DateTime(2016, 1, 25)));




      theOriList =  theOriList.OrderBy(x => x.fromId).ThenBy(x=> x.toId).ToList();

        int addnew = 0;
        for (int i = 0; i < theOriList.Count; i++)
        {

            for (int j = i + 1; j < theOriList.Count; j++)
            {
                if ((theOriList[i].fromId == theOriList[j].fromId) && (theOriList[i].toId == theOriList[j].toId))
                {
                    if ((theOriList[i].fromDate <= theOriList[j].fromDate) && (theOriList[j].fromDate <= theOriList[i].toDate))
                    {
                        if (theOriList[j].toDate > theOriList[i].toDate)
                        {
                            maxDate = theOriList[j].toDate;
                            minDate = theOriList[i].fromDate;

                        }
                        else if (theOriList[j].toDate < theOriList[i].toDate)
                        {
                            maxDate = theOriList[i].toDate;
                            minDate = theOriList[i].fromDate;

                        }

                    }

                    else if (theOriList[i].fromDate > theOriList[j].fromDate)
                    {
                        if (theOriList[i].toDate <= theOriList[j].toDate)
                        {
                            maxDate = theOriList[j].toDate;
                            minDate = theOriList[j].fromDate;
                        }

                        else if (theOriList[i].toDate > theOriList[j].toDate)
                        {
                            maxDate = theOriList[i].toDate;
                            minDate = theOriList[j].fromDate;
                        }

                    }

                    else if ((theOriList[j].fromDate > theOriList[i].toDate))
                    {
                        //Add directly
                        addnew = 1;
                    }

                }

            }

            if (addnew != 1)
            {

                theTempList.Add(new ItemDetails(theOriList[i].fromId, theOriList[i].toId, minDate, maxDate));
            }
            else if (addnew == 1)

                theTempList.Add(new ItemDetails(theOriList[i].fromId, theOriList[i].toId, theOriList[i].fromDate, theOriList[i].toDate));
        }


        theTempList = theTempList.OrderBy(x => x.fromId).ThenBy(x => x.toId).ToList();





        foreach (ItemDetails x in theTempList)
        {

            Console.WriteLine("FromId: " + x.fromId + "\tToId: " + x.toId + "\tFromDate:" + x.fromDate + "\tToDate:" + x.toDate);
        }

        Console.ReadKey();
    }


}

4 个答案:

答案 0 :(得分:1)

GroupBy字段需要From,To,然后分别从MinMax查找FromDateToDate个日期。

theOriList.GroupBy(x=> new {x.From, x.To })
          .Select(x=> new ItemDetails(x.Key.From,x.Key.To,x.Min(m=>m.FromDate), x.Max(m=>m.ToDate)))
          .ToList();

选中此Demo

答案 1 :(得分:0)

我像这样使用GroupBy和Projection

        struct Thing
        {
            public string From { get; }
            public string To { get; }
            public DateTime FromDate { get; }
            public DateTime ToDate { get; }

            public Thing(string @from, string to, DateTime fromDate, DateTime toDate)
            {
                From = @from;
                To = to;
                FromDate = fromDate;
                ToDate = toDate;
            }

            public override string ToString()
            {
                return $"{From}-{To} Dates: {FromDate.ToShortDateString()} - {ToDate.ToShortDateString()}";
            }
        }

        [Test]
        public void Grouping()
        {
            var items = new List<Thing>
            {
                new Thing("S1", "S2", new DateTime(2016, 1, 1), new DateTime(2016, 1, 1)),
                new Thing("S2", "S3", new DateTime(2016, 2, 1), new DateTime(2016, 3, 14)),
                new Thing("S1", "S2", new DateTime(2016, 1, 5), new DateTime(2016, 1, 20)),
                new Thing("S2", "S3", new DateTime(2016, 1, 25), new DateTime(2016, 2, 25)),
                new Thing("S1", "S2", new DateTime(2016, 1, 21), new DateTime(2016, 1, 25))
            };

            var results = items.GroupBy(i => new {i.From, i.To})
                                                 .Select(grp => new
                                                 {
                                                     grp.Key.From,
                                                     grp.Key.To,
                                                     items = grp.ToList()
                                                 })
                                                 .Select(grpd => new Thing(
                                                     grpd.From, 
                                                     grpd.To, 
                                                     grpd.items.Min(x => x.FromDate), 
                                                     grpd.items.Max(x=> x.ToDate)));

            Assert.That(results, Is.EquivalentTo(new List<Thing>
            {
                new Thing("S1", "S2", new DateTime(2016, 1, 1), new DateTime(2016, 1, 25)),
                new Thing("S2", "S3", new DateTime(2016, 1, 25), new DateTime(2016, 3, 14))
            }));
        }

此处传递的NUnit测试显示了如何按两个属性进行分组,然后选择这些组的最小和最大日期。

答案 2 :(得分:0)

你可以这样做。我对linq不太好。

$ env API_KEY=XXX pm2 start app.js

答案 3 :(得分:0)

尝试linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication10
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("FromID", typeof(string));
            dt.Columns.Add("ToID", typeof(string));
            dt.Columns.Add("FromDate", typeof(DateTime));
            dt.Columns.Add("ToDate", typeof(DateTime));

            dt.Rows.Add(new object[] {"S1", "S2", DateTime.Parse("1/1/2016"), DateTime.Parse("1/15/2016")});
            dt.Rows.Add(new object[] {"S2", "S3", DateTime.Parse("2/1/2016"), DateTime.Parse("3/14/2016")});
            dt.Rows.Add(new object[] {"S1", "S2", DateTime.Parse("1/5/2016"), DateTime.Parse("1/20/2016")});
            dt.Rows.Add(new object[] {"S2", "S3", DateTime.Parse("1/25/2016"), DateTime.Parse("2/25/2016")});
            dt.Rows.Add(new object[] {"S1", "S2", DateTime.Parse("1/21/2016"), DateTime.Parse("1/25/2016")});

            dt = dt.AsEnumerable()
                .OrderBy(x => x.Field<DateTime>("FromDate"))
                .ThenBy(x => x.Field<string>("ToID"))
                .ThenBy(x => x.Field<string>("ToID")).CopyToDataTable();

            for (int rowNum = dt.Rows.Count - 2; rowNum >= 0; rowNum--)
            {
                if ((dt.Rows[rowNum]["FromID"] == dt.Rows[rowNum + 1]["FromID"]) &&
                    (dt.Rows[rowNum]["ToID"] == dt.Rows[rowNum + 1]["ToID"]))
                {
                    dt.Rows[rowNum]["ToDate"] = dt.Rows[rowNum + 1]["ToDate"];
                    dt.Rows[rowNum + 1].Delete();
                }
            }
            dt.AcceptChanges();
        }
    }
}