0

I have a List that contains a Dictionary list. The Dictionary contains the key "date" with a DateTime value, and various other keys that correspond to values of decimal numbers. I want to group by date and do the average of each decimal numbers.

I've made this before with linq but can't seem to figure it out with a dictionary.

List<object> list = new List<object>();
Dictionary<string,object> dictionary = new Dictionary<string,object>
dictionary.Add("date", date)
foreach( field in json )
{
    dictionary.Add(field.Key, field.Value)
}
list.Add(dictionary);
list = list.GroupBy(m => (DateTime)m["date"], m => "not sure what to do here", (k,d) => (new object[]{k, d.Average()}).ToList()).ToList();

m["date"] doesn't work either.

The dictionary has the following data:

  1. "Key" Data -"Value" 05/29/2015 05:50:06
  2. "Key" Processing time - "Value" 6
  3. "Key" Disk usage - "Value" 2

When there's no more items in the json, the dictionary is added to the list and the process is repeated.

Kingsley
  • 14,398
  • 5
  • 31
  • 53
Hugo Silva
  • 19
  • 2
  • 6
    Can you post what you've tried? It's easier to build an answer from what didn't work for you – NibblyPig Mar 19 '19 at 15:25
  • I will not do your homework :p sorry buddy – pix Mar 19 '19 at 15:27
  • The date items probably very by less than a second and will not group. So use the DateTime property 'Date' to truncate the dates to the start of the day at midnight before grouping. – jdweng Mar 19 '19 at 15:29
  • 3
    As others said: this site is not about asking for complete solutions, but for getting help in what doesn't work for you. Please provide at least the code for your objects and what you tried to do. – Nicolas Mar 19 '19 at 15:30
  • dictionary key is unique value, datetime must have unique value. you can to that by creating a temp list without time form the datetime value from dictionary. – Hasan Mahmood Mar 19 '19 at 15:33
  • Sounds like you should use a custom class rather than a dictionary.. – Gilad Green Mar 19 '19 at 15:34
  • @jdweng I already did that, I truncated the dates by hour. – Hugo Silva Mar 19 '19 at 15:34
  • 2
    @HugoSilva - please show both what you have tried but also some example data of such a dictionary – Gilad Green Mar 19 '19 at 15:40
  • Try something like following : Dictionary dict = new Dictionary(); var groups = dict.GroupBy(x => new DateTime(x.Key.Year, x.Key.Month, x.Key.Day, x.Key.Hour, 0,0)); var results = groups.Select(x => new { date = x.Key, average = x.Average(y => y.Value) }).ToList(); – jdweng Mar 19 '19 at 15:45

1 Answers1

1

From your description it seems like you are using a dictionary to represent "fields"/"properties" kinds and their values, and that they are connected to each:

The Dictionary contains the key "date" with a DateTime value, and various other keys tha correspond to values of decimal numbers

If that is the case you should better create a custom class with each of these keys as a different property of the class. Something like:

public class YourClass 
{
    public Date DateTime { get; set; }
    public int SomeProperty1 { get; set; }
    public int SomeProperty2 { get; set; }
    // ....
}

Once you do that, instead of having a List<Dictionary<string,object>> then have a List<YourClass>. Now it will be easy to perform the linq you want:

I wanna group by date and do the average of each decimal numbers.

var result = listOfCustomTypes.GroupBy(i => i.DateTime)
                              .Select(g => new YourClass {
                                  Date = g.Key,
                                  SomeProperty1 = g.Average(i => i.SomeProperty1),
                                  SomeProperty2 = g.Average(i => i.SomeProperty2),
                              });

Last, as your data is originally of JSON format you could:

Gilad Green
  • 36,708
  • 7
  • 61
  • 95