6

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"
          }
        }
      }
    }
  }
}   
6
  • Sounds like a cool project! What seems to be the problem? Commented Jun 17, 2015 at 19:38
  • Ive tried using LINQ, Jtoken, Jpath, and others and all fail or return empty. So im reaching out to the community Commented Jun 17, 2015 at 19:44
  • Try this with JSON.NET (you'll need using Newtonsoft.Json after you've added the Nuget package): dynamic d = JsonSerializer.Deserialize(yourJsonString); then use d.partner.campaign.round1.def123.community.choicec to access the choice number. Commented Jun 17, 2015 at 19:54
  • why dynamic ? there must have been a concrete calss. Commented Jun 17, 2015 at 20:38
  • There's no "cid1" property in your JSON. Just to confirm, you want to compare the values of the "choicec": 28 and "choicec": 33 properties to check if they're in order? Commented Jun 18, 2015 at 6:04

1 Answer 1

1

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;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Amazing, thorough and helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.