提前致谢。我感谢任何帮助。
我想比较两个相同类型和结构的任意JTokens(来自NewtonSoft的Json.Net)。
static int CompareTokens(JToken x, JToken y);
// possible output: 0 / 1 / -1
主要目标是能够使用此方法对两个Json字符串进行排序,这样即使在开始时它们具有相同的数据,但是顺序不同,最后这些是两个完全相同的字符串所以排序标准并不重要,重要的是这个标准总是一样的。并且应该考虑每个小数据元素。
JToken可以是以下几种类型之一:Array, Boolean, Date, Float, Guid, Integer, Null, Object, Property, String, TimeSpan, Uri
。我没有考虑比较Bytes, Comment, Constructor, None, Undefined, Raw
。
这是一个很常见的问题。如果我弄明白该怎么做,我会给它加一个+100。对不起我的英语。
答案 0 :(得分:8)
在Linq-to-JSON中,JValue
表示原始值(字符串,数字,布尔值等)。它实现了IComparable<JValue>
,因此Json.NET负责为您排序原始值。
基于此,您将需要以递归方式并行地下降两个fit f(x) data via *parameter*
plot f(x), data using ((abs($2-f($1)) > threshold) ? $2 : NaN)
对象层次结构。当您遇到具有不同.Net类型的第一个令牌或不同的属性(如果不是JToken
)或具有不同的值(如果是JValue
)时,您需要返回比较值。
请记住以下内容:
JValue
和JArray
的子令牌。JConstructor
的子令牌不是,因此需要以一种稳定,对称的方式进行比较。按照属性名称的顺序行走似乎都有效。JObject
,所以不要尝试,并抛出异常。以下是原型实现:
JRaw
轻度测试prototype fiddle。
答案 1 :(得分:2)
实际上,这可以用更少的代码完成。不太好,因为使用 字符串比较 而不是JValue
比较。
以下不是我自己问题的确切答案,但目标已实现。
public static JToken Normalize(this JToken token)
{
var result = token;
switch (token.Type)
{
case JTokenType.Object:
var jObject = (JObject)token;
if (jObject != null && jObject.HasValues)
{
var newObject = new JObject();
foreach (var property in jObject.Properties().OrderBy(x => x.Name).ToList())
{
var value = property.Value as JToken;
if (value != null)
{
value = Normalize(value);
}
newObject.Add(property.Name, value);
}
return newObject;
}
break;
case JTokenType.Array:
var jArray = (JArray)token;
if (jArray != null && jArray.Count > 0)
{
var normalizedArrayItems = jArray
.Select(x => Normalize(x))
.OrderBy(x => x.ToString(), StringComparer.Ordinal);
result = new JArray(normalizedArrayItems);
}
break;
default:
break;
}
return result;
}