I’m trying to extract values from json using Newtonsoft, but I’m having some problems.
Below is the json snippet I use:
{
"result": {
"areas": [
{
"area": 1,
"items": [
{
"name": "name1",
"numbers": [
2,
2,
2,
1
],
"value": 0.3
},
{
"name": "name2",
"numbers": [
0,
1,
0,
1
],
"value": 0.6
},
{
"name": "name3",
"numbers": [
-2,
3,
1,
1
],
"value": 0.5
}
]
},
{
"area": 2,
"items": [
{
"name": "name4",
"numbers": [
1,
2,
3,
4
],
"value": 0.7
}
]
}
]
}
}
My task is to first filter by area (I need data only from area 1) and then select those items that meet the conditions for numbers:
- 1st number = 2 or = -2,
- 2nd number > 1,
- 3rd number > 0,
- 4th number = 1,
and then calculate the average value for these selected items.
In this case, I want to select items 1 and 3, i.e. to get an average of 0.4.
I first tried to do it in one filter with multiple conditions:
IEnumerable<JToken> numbers = jo.SelectTokens("$...items[?( (@.numbers[0] == 2 || @.numbers[0] == -2 ) && @.numbers[1] > 1 && @.numbers[2] > 0 && @.numbers[3] == 1)].value");
I got an error in this case because I can’t use additional brackets in the query, and I don’t know how else to check all the conditions.
Then I wrote each query separately and connected them using the Intersect() function:
IEnumerable<JToken> numbers0 = jo.SelectTokens("$...items[?(@.numbers[0] == 2 || @.numbers[0] == -2)]");
IEnumerable<JToken> numbers1 = jo.SelectTokens("$...items[?(@.numbers[1] > 1)]");
IEnumerable<JToken> numbers2 = jo.SelectTokens("$...items[?(@.numbers[2] > 0)]");
IEnumerable<JToken> numbers3 = jo.SelectTokens("$...items[?(@.numbers[3] == 1)]");
IEnumerable<JToken> numbers = numbers0.Intersect(numbers1.Intersect(numbers2.Intersect(numbers3)));
In this case, however, I am not able to extract the value and the entire json fragment is returned to me.
In both cases, I am unable to include the area filtering condition, the returned token is empty:
IEnumerable<JToken> area = jo.SelectTokens("$..areas[?( @.area == 1)]");
Am I doing something wrong? Maybe this can be fixed somehow without changing the approach.
And if this is not possible, what technique do you recommend? I’ve read a bit about LINQ and will try that next if the current task is unsolvable, unless you think there’s something even better.
Please also write if any important information is missing.
Regards! 😀
BezqyczekPL is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.