user9969
user9969

Reputation: 16040

Could you help filtering a collection and creating another in linq

I have created the following to explain my problem.

Given a list with PayDates and periods. I Need to create a new list containing 1 item for each period that is nearest to its Pay Date.

So given the example the list should return 2 items "1st of the month" and "17th of the month" as they are the closest to their paydate in their period

any suggestions?

 private static List<Schedule> GetFilteredScheduleList()
  {
     List<Schedule>oldScheduleList=new List<Schedule>();
     oldScheduleList.Add(new Schedule { PayDate = new DateTime(2011, 1, 1), Id = 1, Name = "1st of the month", Period = SchedulePeriod.Monthly });
     oldScheduleList.Add(new Schedule { PayDate = new DateTime(2011, 1, 4), Id = 1, Name = "4th of the month", Period = SchedulePeriod.Monthly });
     oldScheduleList.Add(new Schedule { PayDate = new DateTime(2011, 1, 19), Id = 1, Name = "19th of the month", Period = SchedulePeriod.Monthly });
     oldScheduleList.Add(new Schedule { PayDate = new DateTime(2012, 1, 3), Id = 1, Name = "3rd of each quarter", Period = SchedulePeriod.Quarterly });
     oldScheduleList.Add(new Schedule { PayDate = new DateTime(2013, 1, 8), Id = 1, Name = "8th each quarter", Period = SchedulePeriod.Quarterly });
     oldScheduleList.Add(new Schedule { PayDate = new DateTime(2011, 1, 17), Id = 1, Name = "17th of the month", Period = SchedulePeriod.Quarterly });

    // Need to create a new list containing 1 item for each period that is nearest to its Pay Date.Starting point it's today's date.
    //  so the list should return 2 items "1st of the month" and "17th of the month" as they are the closest to their paydate in their period

     List<Schedule> newScheduleList = oldScheduleList.Where(x=>x.PayDate)
  }

Upvotes: 0

Views: 111

Answers (1)

spender
spender

Reputation: 120496

This should select the Schedule item from each period that is closest to now. Is this what you meant?

oldScheduleList
    .GroupBy(s => s.Period)
    .Select(
        g => g
              .OrderBy(s => Math.Abs((s.PayDate - DateTime.Now).TotalSeconds))
              .First()
    )

Edit:

In response to your comment, to get the first item for the period is a little simpler. I've commented a Where clause. This will get the first in period from now (i.e. dates that have expired are ignored)

oldScheduleList
    .GroupBy(s => s.Period)
    .Select(
        g => g
              //.Where(s => s.Paydate >= DateTime.Now) //filter expired dates
              .OrderBy(s => s.PayDate)
              .First()
    )

Upvotes: 4

Related Questions