C
C#2y ago
malkav

✅ Sorting nested

So I've got this data model that looks something like this (some parts of the fields have been omitted as they are irrelevant)
public class UserMonth
{
// ...
public int Month {get;set;}
public int Year {get;set;}
public List<DaysWorked> DaysWorked {get;set;}
// ...
}

public class DaysWorked
{
public DateTime Date {get;set;}
// ...
}
public class UserMonth
{
// ...
public int Month {get;set;}
public int Year {get;set;}
public List<DaysWorked> DaysWorked {get;set;}
// ...
}

public class DaysWorked
{
public DateTime Date {get;set;}
// ...
}
I'm probably thinking too hard here and that's why I'm missing something simple, so I came here for help I want to do the following in my component: I've got a List<UserMonth> in my component, and I want to render a table by week. The user selects a month and a year they wish to view, and I am supposed to find the UserMonth that was selected (List<UserMonth>.Select(x => x.Month == SelectedMonth && x.Year == SelectedYear) .. should be easy enough) Then I need to seperate the List<DaysWorked> into a nested list: List<List<DaysWorked>> where I sort each week's dates in its own list, and add that list to the list (but keep it sorted?) (Or if there is a better way I'd love to hear it) and then I have to render basically for each week, its own table So does anyone have any ideas on how to do this?
10 Replies
malkav
malkavOP2y ago
I basically gotten so far as to make a Trunk method:
namespace Util.Helpers;

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

using IEnumerator<T> enumerator = source.GetEnumerator();
while (enumerator.MoveNext())
{
int index = 0;
List<T> trunk = new(trunkSize);

do
{
trunk.Add(enumerator.Current);
} while (trunk.Count < trunkSize && enumerator.MoveNext());

yield return trunk;
}
}
}
namespace Util.Helpers;

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

using IEnumerator<T> enumerator = source.GetEnumerator();
while (enumerator.MoveNext())
{
int index = 0;
List<T> trunk = new(trunkSize);

do
{
trunk.Add(enumerator.Current);
} while (trunk.Count < trunkSize && enumerator.MoveNext());

yield return trunk;
}
}
}
Now I only have to figure out when the first date of the week starts, and make the first list somewhere between 1 and 7 based on when the date starts in the week (DayOfWeek?) and then create a new list of 7 for each other item I have in the trunk.. Then I hope I can render that seperately?
sibber
sibber2y ago
you can use Linq GroupBy and Calendar.GeWeekOfYear
MODiX
MODiX2y ago
Cyberrex#8052
REPL Result: Success
using System.Globalization;

List<DateTime> l = new()
{
new(2022, 12, 1),
new(2022, 12, 3),
new(2022, 12, 4),
new(2022, 12, 7),
new(2022, 12, 12),
new(2022, 12, 16),
new(2022, 12, 27),
new(2022, 12, 30),
};

var groups = l.GroupBy(d => CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d, CalendarWeekRule.FirstFullWeek, DayOfWeek.Sunday));

int c = 0;
foreach (var g in groups)
{
Console.WriteLine($"Week {c++}:");
Console.WriteLine(string.Join(", ", g.Select(d => d.ToString("MMM d ddd"))));
Console.WriteLine();
}
using System.Globalization;

List<DateTime> l = new()
{
new(2022, 12, 1),
new(2022, 12, 3),
new(2022, 12, 4),
new(2022, 12, 7),
new(2022, 12, 12),
new(2022, 12, 16),
new(2022, 12, 27),
new(2022, 12, 30),
};

var groups = l.GroupBy(d => CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d, CalendarWeekRule.FirstFullWeek, DayOfWeek.Sunday));

int c = 0;
foreach (var g in groups)
{
Console.WriteLine($"Week {c++}:");
Console.WriteLine(string.Join(", ", g.Select(d => d.ToString("MMM d ddd"))));
Console.WriteLine();
}
Console Output
Week 0:
Dec 1 Thu, Dec 3 Sat

Week 1:
Dec 4 Sun, Dec 7 Wed

Week 2:
Dec 12 Mon, Dec 16 Fri

Week 3:
Dec 27 Tue, Dec 30 Fri
Week 0:
Dec 1 Thu, Dec 3 Sat

Week 1:
Dec 4 Sun, Dec 7 Wed

Week 2:
Dec 12 Mon, Dec 16 Fri

Week 3:
Dec 27 Tue, Dec 30 Fri
Compile: 754.215ms | Execution: 104.603ms | React with ❌ to remove this embed.
malkav
malkavOP2y ago
Hrm, that's an interesting one. Let's see if I can replicate with what I have Wait so the "Key" part of IGrouping in this case, is that the int of the week or the index of the item?
sibber
sibber2y ago
its what it groups by in this case the number of week of year, yes
malkav
malkavOP2y ago
okay, so if I select November as selectedMonth (aka int 10) do I then still get IGrouping<int, DaysWorked>.Key to be starting at 0, or does it actually start at the week number of that month? trying to figure out because of this:
<table class="table-borderless">
<tr>
@foreach (IGrouping<int, DaysWorked> list in _group)
{
<thead>
<th colspan="2">Week #@(list)</th>
</thead>
foreach (var item in list)
{
<th>@item.DayWorked.Day / @item.DayWorked.Month</th>
<td>@* Create form of "add item here" *@ Data</td>
}
}
</tr>
</table>
<table class="table-borderless">
<tr>
@foreach (IGrouping<int, DaysWorked> list in _group)
{
<thead>
<th colspan="2">Week #@(list)</th>
</thead>
foreach (var item in list)
{
<th>@item.DayWorked.Day / @item.DayWorked.Month</th>
<td>@* Create form of "add item here" *@ Data</td>
}
}
</tr>
</table>
where I'm trying to figure out what to make of Week #@(list).. should this be list.Key or should it be somethig else to get the actual weeknumber of the year of the currently selected month but I guess I'll try it out, once I get the project to build 😅
sibber
sibber2y ago
week number of the whole year so the first week of november would be
MODiX
MODiX2y ago
Cyberrex#8052
REPL Result: Success
CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(new DateTime(2022, 10, 1), CalendarWeekRule.FirstFullWeek, DayOfWeek.Sunday)
CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(new DateTime(2022, 10, 1), CalendarWeekRule.FirstFullWeek, DayOfWeek.Sunday)
Result: int
39
39
Compile: 432.284ms | Execution: 24.594ms | React with ❌ to remove this embed.
sibber
sibber2y ago
so 39th week of the year
malkav
malkavOP2y ago
Awesome, thanks! I'm testing it now You sir, are my hero of today! Thanks so much! It works wonders 😁
Want results from more Discord servers?
Add your server