C# -- 从 JSON 字符串中获取并比较值

6
我需要从JSON字符串中提取值以进行比较。我只需要验证它们是否按顺序排列(升序/降序)。我打算检查第一个和第二个“choices”并进行比较。我不需要更高级的功能。
编辑/更新: 在这种类型的查询中如何使用通配符(*)来跳过每个段?
               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"
          }
        }
      }
    }
  }
}   

听起来是个很酷的项目!有什么问题吗? - cbr
我尝试使用LINQ、Jtoken、Jpath等方法,但都失败或返回空值。因此,我正在向社区寻求帮助。 - Michael Meritt
尝试使用JSON.NET(在添加Nuget包后,您需要using Newtonsoft.Json):dynamic d = JsonSerializer.Deserialize(yourJsonString); 然后使用 d.partner.campaign.round1.def123.community.choicec 访问选择号码。 - cbr
为什么要使用 dynamic?一定有一个具体的类存在。 - Amit Kumar Ghosh
你的JSON中没有“cid1”属性。只是确认一下,你想比较“choicec”: 28和“choicec”: 33这两个属性的值,以检查它们是否按顺序排列? - dbc
"context variables" 会传入 "choicec"。但你是正确的。 - Michael Meritt
1个回答

1
你遇到困难的原因可能是 JSON 层次结构中两个 "choicec" 属性的深度不同。第一个位于 "round2" 下面,而第二个则不是。因此,简单的索引无法起作用。
假设你能使用 Json.NET,你的选项有:
  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".

使用Mikkel R. Lund这个问题中提供的IsOrdered扩展:

public static class EnumerableExtensions
{
    // Taken from https://dev59.com/V3jZa4cB1Zd3GeqPh8WE
    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;
    }
}

1
惊人、全面和有益。 - Michael Meritt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接