Отвечая на ваш вопрос в двух частях,
Часть 1
Первая часть состоит из нескольких шагов
- Десериализация существующего Json в пользовательские структуры данных
- Изменение и создание новых структур данных
При использовании Linq можно выполнить следующие шаги:
var parsedData = JsonConvert.DeserializeObject<RootObject>(str).Results.GroupBy(x=> x.Category.First())
.Select(x=>
new {
name= x.Key,
data = x.GroupBy(c=>c.Category.Last())
.Select(c=> new {value=c.Sum(f=>f.Cost),name=c.Key})
});
Где RootObject определяется как
public class Result
{
public string Description { get; set; }
public double Cost { get; set; }
public List<string> Category { get; set; }
}
public class RootObject
{
[JsonProperty("results")]
public List<Result> Results { get; set; }
}
Часть 2
Вторая часть должна быть выполнена в зависимости от того, как вы хотите, чтобы Json был отформатирован. Если вы наблюдаете ожидаемый результат, указанный в OP, это не похоже на действительный Json. Упрощая его для наглядности, строка Json выглядит следующим образом
{
name : "Online",
data: [....],
name : "Transport",
data: [...],
}
Как уже отмечалось, поля имени и данных дублируются в пределах json. Если вы хотите получить результат именно таким образом, вам нужно сериализовать Json, полученный в Part 1 , и изменить его, используя манипуляции со строками. Например,
var jsonCollection = parsedData.Select(x=> Regex.Replace(JsonConvert.SerializeObject(x,Newtonsoft.Json.Formatting.Indented),@"^{|}$",string.Empty));
var finalResult = $"{{{string.Join(",",jsonCollection)}}}";
Выход
{
"name": "Online",
"data": [
{
"value": 9.0,
"name": "Games"
},
{
"value": 3.0,
"name": "Grocery"
}
]
,
"name": "Transport",
"data": [
{
"value": 6.0,
"name": "Bus"
},
{
"value": 10.0,
"name": "Train"
}
]
}
Если желаемый результат должен быть действительным json, то вы можете убедиться, что это массив. Например,
[
{
name : "Online",
data: [....]
},
{
name : "Transport",
data: [...],
}
]
Затем вы можете сериализовать результат, который вы получили в Part 1 напрямую.
var finalResult = JsonConvert.SerializeObject(parsedData, Newtonsoft.Json.Formatting.Indented);
Выход
[
{
"name": "Online",
"data": [
{
"value": 9.0,
"name": "Games"
},
{
"value": 3.0,
"name": "Grocery"
}
]
},
{
"name": "Transport",
"data": [
{
"value": 6.0,
"name": "Bus"
},
{
"value": 10.0,
"name": "Train"
}
]
}
]
Демонстрационный код