Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# -- Get, then compare values from JSON string

Tags:

json

c#

I need to extract values from a JSON string so I can compare them. I only need to verify that they are in order (ascending/descending). I was going to check the first and second 'choices' and compare. I don't anything more advanced.

EDIT/UPDATE: How could I use wildcards (*) in this type of query to skip having each segment?

               string one = (string)o[this.Context[*WILDCARD*]["cid1"]].ToString();


           /* this works, but has too many []
           string one = (string)o[this.Context["partner"]]
               [this.Context["campaign"]]
               [this.Context["segment1"]]
               [this.Context["segment2"]]
               [this.Context["qid2"]]
               ["community"]
               [this.Context["cid1"]].ToString();
           */


{
  "partner": {
    "campaign": {
      "round1": {
        "round2": {
          "def123": {
            "community": {
              "choicec": 28
            },
            "user": {
              "choice": "choicec",
              "writeDateUTC": "2015-06-15T17:21:59Z"
            }
          }
        },
        "abc321": {
          "community": {
            "choicec": 33
          },
          "user": {
            "choice": "choicec",
            "writeDateUTC": "2015-06-15T17:21:59Z"
          }
        }
      }
    }
  }
}   
like image 351
Michael Meritt Avatar asked Jun 17 '15 19:06

Michael Meritt


1 Answers

The reason you are having some difficulty may be that the two "choicec" properties are not at the same depth in the JSON hierarchy. The first is underneath "round2" while the second is not. Thus straightforward indexing will not work.

Assuming that you are able to use Json.NET, your options are:

  1. Use Descendants to look for all properties named "choicec" and check if they are ordered:

        var obj = JObject.Parse(json);
        bool inOrder = obj.Descendants()
            .OfType<JProperty>()
            .Where(p => p.Name == "choicec")
            .Select(p => (int)p.Value)
            .IsOrdered();
    
  2. Use SelectTokens with JsonPath wildcards to restrict the search to a portion of your JSON, if there happen to be other properties named "choicec" in your hierarchy that are not relevant to the query:

        // Find all properties named "choicec" under "community" recursively under "campaign" under "partner".
        bool inOrder = obj.SelectTokens("partner.campaign..community.choicec")
            .Select(o => (int)o)
            .IsOrdered();
    

    Here .. is a wildcard meaning "recursive descent".

Using the following IsOrdered extension from this question by Mikkel R. Lund:

public static class EnumerableExtensions
{
    // Taken from http://stackoverflow.com/questions/19786101/native-c-sharp-support-for-checking-if-an-ienumerable-is-sorted
    public static bool IsOrdered<T>(this IEnumerable<T> collection, IComparer<T> comparer = null)
    {
        if (collection == null)
            throw new ArgumentNullException();
        comparer = comparer ?? Comparer<T>.Default;

        using (var enumerator = collection.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                var previous = enumerator.Current;

                while (enumerator.MoveNext())
                {
                    var current = enumerator.Current;

                    if (comparer.Compare(previous, current) > 0)
                        return false;

                    previous = current;
                }
            }
        }

        return true;
    }
}
like image 50
dbc Avatar answered Sep 20 '22 13:09

dbc