c# - Combining consecutive date period -


i have date period list , period doesn't overlap

|startdate| enddate| | null    |  1/12  | | 2/12    |  null  | | null    |  4/12  | | 6/12    |  8/12  | | 9/12    |  null  | | null    |  10/12 | | 11/12   |  null  | 

i have combine period list shown following:

|startdate| enddate| | null    |  1/12  | | 2/12    |  4/12  | | 6/12    |  8/12  | | 9/12    |  10/12 | | 11/12   |  null  | 

here solution think not smart way

        var datelist = periodlist.selectmany(x => new[] {              new {date = x.item1, type = "s"},              new {date = x.item2, type = "e"}          }).where(x => x.date != null).orderby(x => x.date).toarray();          var result = new list<tuple<datetime?, datetime?>>();         int = 0;                 {             if (i == 0 && datelist[i].type == "e")             {                 result.add(new tuple<datetime?, datetime?>(null, datelist[i].date));             }             else if (i + 1 == datelist.count() && datelist[i].type == "s")             {                 result.add(new tuple<datetime?, datetime?>(datelist[i].date, null));             }             else             {                 if (datelist[i].type == "s" && datelist[i+1].type == "e")                 {                     result.add(new tuple<datetime?, datetime?>(datelist[i].date, datelist[i + 1].date));                     i++;                 }                                 }             i++;         } while (i < datelist.count()); 

my solution may seem longer, cleaner in opinion. consider have period class (instead of tuple<datetime?, datetime?>) below:

public class period {     public datetime? startdate { get; set; }     public datetime? enddate { get; set; } } 

add dates list of periods:

// make list of periods ready list<period> periodlist = //prepare periods; 

get start dates , end dates separately eliminating null ones:

// start dates list<datetime> startdates = periodlist     .where(p => p.startdate.hasvalue)     .select(p => p.startdate.value)     .tolist();  // end dates list<datetime> enddates = periodlist     .where(p => p.enddate.hasvalue)     .select(p => p.enddate.value)     .tolist(); 

then other operations:

// clear list of periods periodlist.clear();  // add start dates bigger last end date null end date period startdates.where(s => s > enddates.max())     .tolist()     .foreach(s => periodlist.add(new period() { startdate = s, enddate = null }));  // add end dates smaller first start date null start date period enddates.where(e => e < startdates.min())     .tolist()     .foreach(e => periodlist.add(new period() {startdate = null, enddate = e}));  // match other dates , add them list startdates.where(s => s < enddates.max())     .tolist()     .foreach(s => periodlist.add(new period()                                 {                                     startdate = s,                                     enddate = enddates.where(e => e > s).min()                                 }));  // oder period list periodlist = periodlist.orderby(p => p.startdate).tolist(); 

you can test .net fiddle demo here.

i hope helpful.


Comments

Popular posts from this blog

apache - PHP Soap issue while content length is larger -

asynchronous - Python asyncio task got bad yield -

javascript - Complete OpenIDConnect auth when requesting via Ajax -