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"
          }
        }
      }
    }
  }
}   
Michael Meritt
  • 383
  • 5
  • 18
  • Sounds like a cool project! What seems to be the problem? – cbr Jun 17 '15 at 19:38
  • Ive tried using LINQ, Jtoken, Jpath, and others and all fail or return empty. So im reaching out to the community – Michael Meritt Jun 17 '15 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. – cbr Jun 17 '15 at 19:54
  • why `dynamic` ? there must have been a concrete calss. – Amit Kumar Ghosh Jun 17 '15 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? – dbc Jun 18 '15 at 06:04
  • "choicec" is fed in by context variables. But you are correct – Michael Meritt Jun 18 '15 at 20:36

1 Answers1

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;
    }
}
dbc
  • 104,963
  • 20
  • 228
  • 340