C# -- 获取,然后比较 JSON 字符串中的值
本文关键字:字符串 JSON 比较 获取 然后 | 更新日期: 2023-09-27 17:56:44
我需要从JSON字符串中提取值,以便进行比较。我只需要验证它们是否按顺序排列(升序/降序)。我打算检查第一个和第二个"选择"并进行比较。我没有更高级的东西。
编辑/更新:如何在这种类型的查询中使用通配符 (*) 来跳过每个段?
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"
}
}
}
}
}
}
遇到困难的原因可能是两个"choicec"
属性在 JSON 层次结构中的深度不同。 第一个在"round2"
下面,而第二个不在。 因此,直接索引将不起作用。
假设您能够使用 Json.NET,您的选项是:
-
使用
Descendants
查找名为"choicec"
的所有属性,并检查它们是否已排序:var obj = JObject.Parse(json); bool inOrder = obj.Descendants() .OfType<JProperty>() .Where(p => p.Name == "choicec") .Select(p => (int)p.Value) .IsOrdered();
-
如果层次结构中恰好存在与查询无关的其他名为
"choicec"
的属性,请使用SelectTokens
和 JsonPath 通配符将搜索限制为 JSON 的一部分:// 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();
这里
..
是一个通配符,意思是"递归下降"。
使用Mikkel R. Lund对这个问题的以下IsOrdered
扩展:
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;
}
}