简体   繁体   中英

FInd Max value from JSON Array

I have a JSON like this

    {
    "name": "Reporta",
    "assignments": [
        {
          "person_id": 638020,
          "hours_logged": 25.5
        },
        {
          "person_id": 638020,
          "hours_logged": 35.5
        }
    ]
    }

I have to find the first person id from assignments array and i followed this code

    JObject lp_ask = JObject.Parse(response_json);
    int assignee = (int)lp_ask["assignments"][0]["person_id"];   

But now i have to find the person_id who logged max hours from the array . I can do a foreach loop and then can find max value , but is any direct option available

Best way would be to deserialize to a set of static classes, but if you don't want or cannot do that - you can query over raw JSON too:

var person = lp_ask["assignments"]
    .OrderByDescending(c => c["hours_logged"].Value<double>())        
    .Select(c => c["person_id"].Value<int>())
    .First();

I tried to solve this issue on database level using SQL Server JSON support (for SQL Server 2016 and later)

Here is the sample query I used for your requirement

declare @json nvarchar(max) = '
    {
    "name": "Reporta",
    "assignments": [
        {
          "person_id": 638020,
          "hours_logged": 25.5
        },
        {
          "person_id": 638020,
          "hours_logged": 35.5
        }
    ]
    }
'
select 
    person_id, hours_logged
from (
    select
        JSON_VALUE(@json, '$.name') AS [name], 
        JSON_VALUE(@json, '$.assignments['+convert(varchar(2),i)+'].person_id')as person_id,
        JSON_VALUE(@json, '$.assignments['+convert(varchar(2),i)+'].hours_logged') AS hours_logged,
        row_number() over (order by JSON_VALUE(@json, '$.assignments['+convert(varchar(2),i)+'].hours_logged') desc) as rn
    from dbo.NumbersTable(0,10,1) n
) t
where rn = 1

Please note that I used a numbers table SQL function to query each node under assignments.

I sort the sub-rows for assignments by using Row_Number() function and in main select use filter criteria for row_number() value as 1

Output is as follows

在此处输入图片说明

Create a POCO object (Person_Id, Hours_Logged) that you can deserialize to:

var reports = Jsonconvert.Deserialize<YourObjectName>(response_json);

Then you can use LINQ max function:

var personWithMostHoursLogged = reports.Max(x => x.Hours_Logged);

EDIT: this may help you:

public IDictionary<string, object> DeserializeToDictionary(string input)
{
      dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(input);
      return (IDictionary<string, object>)obj;
}

Use following code:

public static void Main()
{
    var jObject = JObject.Parse(jsonString);  
    var assignments = JsonConvert.DeserilizeObject<Assignment[]>(lp_ask["assignments"].ToString());
    var assignment = assignments.OrderByDescending(i => i.hours_logged).FirstOrDefault();
}

private class Assignment
{
    public double hours_logged { get; set; }

    public int person_id { get; set; }
}

You can easily do it this way, for example if you want to find the maximum value of some token in a json string simply do the following:

int max = JObject.Parse(strJSON)
                .SelectTokens("$..recordDataNumber")
                .Select(s => s.Value<int>())
                .Max();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM