Search code examples
c#.net

Splitting data by week


I have a data object that has a timestamp:

class MyDataObject
{
    public DateTime timestamp { get; set; }
    public int value { get; set; }

    public MyDataObject(DateTime timestamp, int value)
    {
        this.timestamp = timestamp;
        this.value = value;
    }
}

In the main method, I create a lot of these data objects over the timespan of 18 days (2.5 weeks):

    static void Main(string[] args)
    {
        List<MyDataObject> data = new List<MyDataObject>();

        data.Add(new MyDataObject(DateTime.Now, 1));
        data.Add(new MyDataObject(DateTime.Now.AddDays(2), 1));
        data.Add(new MyDataObject(DateTime.Now.AddDays(4), 1));
        data.Add(new MyDataObject(DateTime.Now.AddDays(6), 1));
        data.Add(new MyDataObject(DateTime.Now.AddDays(8), 1));
        data.Add(new MyDataObject(DateTime.Now.AddDays(10), 1));
        data.Add(new MyDataObject(DateTime.Now.AddDays(12), 1));
        data.Add(new MyDataObject(DateTime.Now.AddDays(14), 1));
        data.Add(new MyDataObject(DateTime.Now.AddDays(18), 1));
    }

I need to divide this data by weeks, so that the data between days 1 to 6 need to be placed in an array, data between days 8 to 14 in another, and the one in day 18 goes in another array all by itself.

I need to create a 2D List of some sort and somehow divide the data in an "array of arrays" but I'm stumped. I suspect I need to use List.FindAll but I've never used it before and have no idea how I can use it in this case.


Solution

  • Assuming you can use LINQ, you'd just want something like:

    var groupedByWeek = data.GroupBy(item => GetStartOfWeek(item.timestamp));
    

    ... where GetStartOfWeek would return a DateTime at the start of the given week, e.g.

    public static DateTime GetStartOfWeek(DateTime value)
    {
        // Get rid of the time part first...
        value = value.Date;
        int daysIntoWeek = (int) value.DayOfWeek;
        return value.AddDays(-daysIntoWeek);
    }
    

    That will give you a Sunday-based week. You'd need to adjust it a bit to consider a week starting on Saturday, Monday or whatever.