-2

I have a DateTime list of 14 days in total. each day has 2 times.

This list is sorted by DateTime.

DateTime             DayofWeek
16-03-2021 08:00     Tuesday
16-03-2021 20:00     Tuesday
17-03-2021 08:00     Wednesday
17-03-2021 20:00     Wednesday
18-03-2021 08:00     Thursday
18-03-2021 20:00     Thursday
19-03-2021 08:00     Friday
19-03-2021 20:00     Friday
20-03-2021 08:00     Saturday
20-03-2021 20:00     Saturday
21-03-2021 08:00     Sunday
21-03-2021 20:00     Sunday
22-03-2021 08:00     Monday
22-03-2021 20:00     Monday
23-03-2021 08:00     Tuesday
23-03-2021 20:00     Tuesday
24-03-2021 08:00     Wednesday
24-03-2021 20:00     Wednesday
25-03-2021 08:00     Thursday
25-03-2021 20:00     Thursday
26-03-2021 08:00     Friday
26-03-2021 20:00     Friday
27-03-2021 08:00     Saturday
27-03-2021 20:00     Saturday
28-03-2021 08:00     Sunday
28-03-2021 20:00     Sunday
29-03-2021 08:00     Monday
29-03-2021 20:00     Monday

However, I would like to sort it by day of the week at 7days intervals. (Always Monday first)

Expected Result :

DateTime            DayofWeek
22-03-2021 08:00    Monday
22-03-2021 20:00    Monday
16-03-2021 08:00    Tuesday
16-03-2021 20:00    Tuesday
17-03-2021 08:00    Wednesday
17-03-2021 20:00    Wednesday
18-03-2021 08:00    Thursday
18-03-2021 20:00    Thursday
19-03-2021 08:00    Friday
19-03-2021 20:00    Friday
20-03-2021 08:00    Saturday
20-03-2021 20:00    Saturday
21-03-2021 08:00    Sunday
21-03-2021 20:00    Sunday
29-03-2021 08:00    Monday
29-03-2021 20:00    Monday
23-03-2021 08:00    Tuesday
23-03-2021 20:00    Tuesday
24-03-2021 08:00    Wednesday
24-03-2021 20:00    Wednesday
25-03-2021 08:00    Thursday
25-03-2021 20:00    Thursday
26-03-2021 08:00    Friday
26-03-2021 20:00    Friday
27-03-2021 08:00    Saturday
27-03-2021 20:00    Saturday
28-03-2021 08:00    Sunday
28-03-2021 20:00    Sunday

What is the best way to sort?

Thanks in advance.

ASh
  • 34,632
  • 9
  • 60
  • 82
Song
  • 11
  • 6
  • 2
    IMHO rather bizzare sorting 21-03 followed by 29-03 than followed by 23-03, maybe it is just me but that doesn't seem to make any sense, why wouldn't the monday the 22-03 be between 21-03 and 23-03 – Rand Random Mar 22 '21 at 07:29
  • 2
    About the "duplicate" that isn't what OP is wanting either since than all mondays ragardless of the date will be sorted by DayOfWeek, so every Monday no matter the week will be on first place followed by every Tuesday and so on – Rand Random Mar 22 '21 at 07:54
  • As I said before the Question IMHO makes no sense, at least to me, just because your data doesn't start with a Monday as the lowest value, OP wants to force the Monday in front? OP's data set just happens to starts with 16-03 which happens to be a tuesday, but hell no it has to start with 22-03 which is the monday of next week? Why would anyone want that? Why would it make sense to rearrange dates just to force a monday, into the front? just imagine the dataset only contains dates from Tuesday till Thursday on the same week, are we now creating dates just that a monday is the first? – Rand Random Mar 22 '21 at 08:02
  • You have to explain the logic... – Maciej Los Mar 22 '21 at 09:02

1 Answers1

0

Your specification is not complete.

  • Is it guaranteed that there are no holes in your dates?
  • Are there no missing entries? Every Date has exactly two values?
  • Is the first day of our sequence guaanteed Tuesday, or can it be that your sequence starts on Saturday. What do you want in that case: the first week only Saturday and Sunday?

But let's assume: no holes, no duplicates, the sequence is sorted by DateTime, every Day has exactly two Datetimes, and the first value is on a TuesDay (I hardly think that these preconditions make a useful business model, but hey, it's your question!)

So given these preconditions, you first want to divide your sequence into of 7 days (14 DateTimes). Then you sort every Group with DayOfWeek == first, DayOfWeek == 0 last.

For the first grouping there is no standard LINQ, so we have to extend LINQ with an extension method. If you are not familiar with extension methods, see extension methods demystified. Let's call such a group a Trunk. We'll make Trunks of 7 days:

public IEnumerable<IEnumerable<T>> ToTrunks<T>(IEnumerable<T> source, int trunkSize)
{
    // TODO: decide what to do if source null, or trunkSize <= 0

    using (var enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            // some source data available. Create a Trunk:
            int index = 0;
            var trunk = new List<T>(trunkSize);

            // fill the trunk, until trunk full, or no more data
            do
            {
                trunk.Add(enumerator.Current)
            }
            While(trunk.Count < trunkSize && enumerator.MoveNext();

            // return the Trunk:
            yield return trunk;
        }
    }
}

Usage:

IEnumerable<int> numbers = Enumerable.Range(10, 20); // = 10..29
var trunks = numbers.ToTrunks(8);

Trunk 0: 10, 11, 12, 13, 14, 15, 16, 17
Trunk 1: 18, 19, 20, 21, 22, 23, 24, 25
Trunk 2: 26, 27, 28, 29

We'll divide your input data into Trunks of 7 days, and sort the elements of every Trunk with Monday first. Use SelectMany to flatten the result

To get DayOfWeek Monday first and Sunday last:

(DayOfWeek + 6) % 7.

This will monday Monday (=1) to 0, Tuesday (=2) to 1, Sunday (=0) to 6

IEnumerable<DateTime> myOriginalDates = ...
var result = myOriginalDates.ToTrunks(14)        // 14 values per week
    .SelectMany(trunk => trunk.OrderBy(date => (date.DayOfWeek + 6) % 7);
Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116