Home > OS >  Read and iterate Json using c#
Read and iterate Json using c#

Time:07-18

I have following Json content.

I am trying to retrieve the value from this json data. string[] value = GetMValue(jsonobj, "1"); if i pass 1 to the function, it should return its corresponding MValues in a list. In this case, it should retrun "Physical" and "Non-Physical" in string[] value. similarly, if i pass 3, it should return "package" and "355 ml" in string[] value.

Can you please suggest me how to I achieve this?

Please find the json data and its corresponding class.

{
    "Results": [{
            "Components": [{
                "Attribute": {
                    "Values": [{
                            "Id": "1",
                            "MValue": "Physical"
                        },
                        {
                            "Id": "2",
                            "MValue": "77777722060600"
                        },
                        
                        {
                            "Id": "3",
                            "MValue": "package"
                        }
                    ]
                }

            }]
        },
        {
            "Components": [{
                "Attribute": {
                    "Values": [{
                            "Id": "1",
                            "MValue": "Non-Physical"
                        },                      
                        {
                            "Id": "2",
                            "MValue": "77777745363707"
                        },                      
                        {
                            "Id": "3",
                            "MValue": "355 ml"
                        }
                    ]
                }

            }]
        }
    ],
    "ResultCount": 2
}

Following is the class I created with this json data

public class Attribute
{
    public List<Value> Values { get; set; }
}

public class Component
{
    public Attribute Attribute { get; set; }
}

public class Result
{
    public List<Component> Components { get; set; }
}

public class Rootobject
{
    public List<Result> Results { get; set; }
    public int ResultCount { get; set; }
}

public class Value
{
    public string Id { get; set; }
    public string MValue { get; set; }
}

CodePudding user response:

Having used your exact model classes from the question, I fiddled this:

The "magic" happens in the Find method. I commented the steps, so I hope it's clear.

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.Json;
                    
public class Program
{
    public static string INPUT =  <YOUR JSON STRING>;
    
    public static void Main()
    {
        var result1 = Find("3", INPUT);
        Console.WriteLine($"[{(string.Join(", ", result1))}]");
        
        // Empty if not found.
        var result2 = Find("4", INPUT);
        Console.WriteLine($"[{(string.Join(", ", result2))}]");
    }
    
    public static IEnumerable<string> Find(string id, string input)
    {
        var root = JsonSerializer.Deserialize<Rootobject>(INPUT);
        var result = root.Results
                         .SelectMany(x => x.Components) // Flatten Lists in one List
                         .Select(x => x.Attribute)
                         .SelectMany(x => x.Values) // Again flatten
                         .Where(v => v.Id == id)    // Filter for id
                         .Select(v => v.MValue)     // Return each MValue
                         .ToList();
        return result;
    }
}

See: https://dotnetfiddle.net/4YRPzT

Output:

[package, 355 ml]
[]

CodePudding user response:

I guess you already converted your JSON String to your object structure with something like Newtonsoft.

Then you could use Linq to iterate over your models:

private static string[] GetMValue(Rootobject jsonobj, string v)
        {
            List<string> values = new List<string>();

            jsonobj?.Results?.ForEach(x => x?.Components?.ForEach(component => component?.Attribute?.Values?.ForEach(value =>
            {
                if (value?.Id == v)
                {
                    values.Add(value.MValue);
                }
            })));

            return values.ToArray();
        }

This function will return your expected results. If the Id is not found it will return an empty Array (if you prefer null, just check, if the list is empty before returning it and return null in that case).

I added ? after all properties so it will not break, if any point in your model contains null.

CodePudding user response:

Here is an example of implementation using "for" and "index":

public static string[] GetMValue(Rootobject rootobject, string id)
{
    List<string> mValues = new List<string>();
    for (int iResult = 0; iResult < rootobject.Results.Count; iResult  )
    {
        Result result = rootobject.Results[iResult];
        for (int iComponent = 0; iComponent < result.Components.Count; iComponent  )
        {
            Component component = result.Components[iComponent];
            for (int iValue = 0; iValue < component.Attribute.Values.Count; iValue  )
            {
                Value value = component.Attribute.Values[iValue];
                if (value.Id == id)
                {
                    mValues.Add(value.MValue);
                }
            }
        }
    }
    return mValues.ToArray();
}

...or using Linq:

public static string[] GetMValueLinq(Rootobject rootobject, string id)
{
    return rootobject.Results
        .SelectMany(x => x.Components)
        .SelectMany(x => x.Attribute.Values)
        .Where(x => x.Id == id)
        .Select(x => x.MValue)
        .ToArray();
}

Be careful if your API returns null value, you should add null-check.

CodePudding user response:

you don't need any custom classes at all, try this

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

var results = (JArray)JObject.Parse(json)["Results"];

    string[] value = GetMValue(results, "1");

public string[] GetMValue(JArray results, string id)
{
    return results.SelectMany(r => ((JArray)r["Components"])
                                  .Select(r => ((JArray)r["Attribute"]["Values"])
                                  .Where(r => (string)r["Id"] == id)
                                  .Select(r => (string)r["MValue"])
                                  .First()))
                                  .ToArray();
}
  • Related