Ravi Raj
Ravi Raj

Reputation: 66

Get all the values from JSON based on keyname

I got JSON from some process as following:

{
"Nodename": "Host1",
"OperatingSystem": "OS",
"Release": "3.6.2.1",
"Stats": [{
        "Timestamp": "11/18/2021 18:31:58",
        "Processes": [{
                "Timestamp": "11/18/2021 18:31:58",
                "Processname": "process1",
                "CpuPercent": 0,
                "MemoryPercent": 0.16,
            }, {
                "Timestamp": "11/18/2021 18:31:58",
                "Processname": "process2",
                "CpuPercent": 0,
                "MemoryPercent": 0.46,
            }, {
                "Timestamp": "11/18/2021 18:31:58",
                "Processname": "process3",
                "CpuPercent": 0,
                "MemoryPercent": 0.69,
            }
        ]
    }, {
        "Timestamp": "11/18/2021 18:32:08",
        "Processes": [{
                "Timestamp": "11/18/2021 18:32:08",
                "Processname": "process1",
                "CpuPercent": 0,
                "MemoryPercent": 0.16,
            }, {
                "Timestamp": "11/18/2021 18:32:09",
                "Processname": "process2",
                "CpuPercent": 0,
                "MemoryPercent": 0.46,
            }, {
                "Timestamp": "11/18/2021 18:32:09",
                "Processname": "process3",
                "CpuPercent": 0,
                "MemoryPercent": 0.69,
            }
        ]
    }, {...}
]}

I need to sum all the values based on process as key in another JSON like

{
    "process1": {
        "AverageCpu": xxx,
        "AverageMemory": yyy,
    },
    "process2": {
        "AverageCpu": xxx,
        "AverageMemory": yyy,
    },
    "process3": {
        "AverageCpu": xxx,
        "AverageMemory": yyy,
    }
}

I am trying with normal foreach with "groupby" but not able to get actual result. I do not want to iterate many times as this source JSON can be huge.

Thanks

Upvotes: 0

Views: 64

Answers (1)

Yong Shun
Yong Shun

Reputation: 51485

You can use tools such as Json2Csharp to generate the classes based on JSON.

public class Process
{
    public string Timestamp { get; set; }

    public string Processname { get; set; }

    public int CpuPercent { get; set; }

    public double MemoryPercent { get; set; }
}

public class Stat
{
    public string Timestamp { get; set; }

    public List<Process> Processes { get; set; }
}

public class Root
{
    public string Nodename { get; set; }

    public string OperatingSystem { get; set; }

    public string Release { get; set; }

    public List<Stat> Stats { get; set; }
}

public class GroupedProcessStat
{
    public double AverageCpu {get;set;}
    public double AverageMemory {get;set;}
}
  1. Deserialize JSON to Root class via Newtonsoft.Json.JsonConvert.
  2. Retrieve processes via .SelectMany() from System.Linq.
  3. .GroupBy() processName and convert it to dictionary via .ToDictionary().
using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
var root = JsonConvert.DeserializeObject<Root>(json);
var processes = root.Stats
    .SelectMany(x => x.Processes)
    .ToList();
        
var groupedProcessDict = processes.GroupBy(x => x.Processname)
    .ToDictionary(
        x => x.Key,
        x => new GroupedProcessStat
            {
                AverageCpu = x.Average(y => y.CpuPercent),
                AverageMemory = x.Average(y => y.MemoryPercent)
            });
        
var groupedProcessJson = JsonConvert.SerializeObject(groupedProcessDict);
Console.WriteLine(groupedProcessJson);

Output

{"process1":{"AverageCpu":0.0,"AverageMemory":0.16},"process2":{"AverageCpu":0.0,"AverageMemory":0.46},"process3":{"AverageCpu":0.0,"AverageMemory":0.69}}

Sample Program on .NET Fiddle

Upvotes: 1

Related Questions