提前致谢。感谢您的帮助。
我想比较两个相同类型和结构的任意JToken(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。对不起,我的英语。
在Linq-to-
JSON中,JValue
表示原始值(字符串,数字,布尔值等)。它实现了IComparable<JValue>
,因此Json.NET会为您处理原始值的排序。
在此基础上,您将需要递归JToken
并行地降低两个对象层次结构。当您遇到具有不同.Net类型,不同属性(如果不是JValue
)或具有不同值(如果a
JValue
)的第一个标记时,您需要返回比较值。
请注意以下几点:
JArray
和JConstructor
排序。JObject
不是,因此需要以稳定,对称的方式进行比较。以 属性名称的 顺序行走似乎是可行的。JRaw
,所以不要尝试让异常抛出。以下是原型实现:
public class JTokenComparer : IComparer<JToken>
{
public static JTokenComparer Instance { get { return instance; } }
static JTokenComparer instance;
static JTokenComparer()
{
instance = new JTokenComparer();
}
readonly Dictionary<Type, KeyValuePair<int, IComparer<JToken>>> dict;
JTokenComparer()
{
dict = new Dictionary<Type, KeyValuePair<int, IComparer<JToken>>>
{
// Order chosen semi-arbitrarily. Putting values first seems reasonable though.
{typeof(JValue), new KeyValuePair<int, IComparer<JToken>>(0, new JValueComparer()) },
{typeof(JProperty), new KeyValuePair<int, IComparer<JToken>>(1, new JPropertyComparer()) },
{typeof(JArray), new KeyValuePair<int, IComparer<JToken>>(2, new JArrayComparer()) },
{typeof(JObject), new KeyValuePair<int, IComparer<JToken>>(3, new JObjectComparer()) },
{typeof(JConstructor), new KeyValuePair<int, IComparer<JToken>>(4, new JConstructorComparer()) },
};
}
#region IComparer<JToken> Members
public int Compare(JToken x, JToken y)
{
if (x is JRaw || y is JRaw)
throw new InvalidOperationException("Tokens of type JRaw cannot be sorted");
if (object.ReferenceEquals(x, y))
return 0;
else if (x == null)
return -1;
else if (y == null)
return 1;
var typeData1 = dict[x.GetType()];
var typeData2 = dict[y.GetType()];
int comp;
if ((comp = typeData1.Key.CompareTo(typeData2.Key)) != 0)
return comp;
if (typeData1.Value != typeData2.Value)
throw new InvalidOperationException("inconsistent dictionary values"); // Internal error
return typeData2.Value.Compare(x, y);
}
#endregion
}
abstract class JTokenComparerBase<TJToken> : IComparer<JToken> where TJToken : JToken
{
protected TJToken CheckType(JToken item)
{
if (item != null && item.GetType() != typeof(TJToken))
throw new ArgumentException(string.Format("Actual type {0} of token \"{1}\" does not match expected type {2}", item.GetType(), item, typeof(TJToken)));
return (TJToken)item;
}
protected bool TryBaseCompare(TJToken x, TJToken y, out int comparison)
{
CheckType(x);
CheckType(y);
if (object.ReferenceEquals(x, y))
{
comparison = 0;
return true;
}
else if (x == null)
{
comparison = -1;
return true;
}
else if (y == null)
{
comparison = 1;
return true;
}
comparison = 0;
return false;
}
protected abstract int CompareDerived(TJToken x, TJToken y);
protected int TokenCompare(JToken x, JToken y)
{
var tx = CheckType(x);
var ty = CheckType(y);
int comp;
if (TryBaseCompare(tx, ty, out comp))
return comp;
return CompareDerived(tx, ty);
}
#region IComparer<JToken> Members
int IComparer<JToken>.Compare(JToken x, JToken y)
{
return TokenCompare(x, y);
}
#endregion
}
abstract class JContainerOrderedComparerBase<TJToken> : JTokenComparerBase<TJToken> where TJToken : JContainer
{
protected int CompareItemsInOrder(TJToken x, TJToken y)
{
int comp;
// Dictionary order: sort on items before number of items.
for (int i = 0, n = Math.Min(x.Count, y.Count); i < n; i++)
if ((comp = JTokenComparer.Instance.Compare(x[i], y[i])) != 0)
return comp;
if ((comp = x.Count.CompareTo(y.Count)) != 0)
return comp;
return 0;
}
}
class JPropertyComparer : JTokenComparerBase<JProperty>
{
protected override int CompareDerived(JProperty x, JProperty y)
{
int comp;
if ((comp = x.Name.CompareTo(y.Name)) != 0)
return comp;
return JTokenComparer.Instance.Compare(x.Value, y.Value);
}
}
class JObjectComparer : JTokenComparerBase<JObject>
{
protected override int CompareDerived(JObject x, JObject y)
{
int comp;
// Dictionary order: sort on items before number of items.
// Order both property sequences to preserve reflexivity.
foreach (var propertyComp in x.Properties().OrderBy(p => p.Name).Zip(y.Properties().OrderBy(p => p.Name), (xp, yp) => JTokenComparer.Instance.Compare(xp, yp)))
if (propertyComp != 0)
return propertyComp;
if ((comp = x.Count.CompareTo(y.Count)) != 0)
return comp;
return 0;
}
}
class JArrayComparer : JContainerOrderedComparerBase<JArray>
{
protected override int CompareDerived(JArray x, JArray y)
{
int comp;
if ((comp = CompareItemsInOrder(x, y)) != 0)
return comp;
return 0;
}
}
class JConstructorComparer : JContainerOrderedComparerBase<JConstructor>
{
protected override int CompareDerived(JConstructor x, JConstructor y)
{
int comp;
if ((comp = x.Name.CompareTo(y.Name)) != 0)
return comp;
if ((comp = CompareItemsInOrder(x, y)) != 0)
return comp;
return 0;
}
}
class JValueComparer : JTokenComparerBase<JValue>
{
protected override int CompareDerived(JValue x, JValue y)
{
return Comparer<JToken>.Default.Compare(x, y); // JValue implements IComparable<JValue>
}
}
经过严格测试的原型小提琴。
我正在使用Kafka和Spark 2.1结构化流。我有两个json格式的数据主题,例如: 我需要比较Spark中基于标记的两个流:name,当值相等时,执行一些额外的定义/函数。 如何使用Spark结构化流来做到这一点? 谢谢
假设我有两个列表,现在listOld包含旧员工信息,listNew包含新员工信息 我如何比较这两个列表并返回新列表,其中包含,添加的新员工列表,包含,删除的员工列表,包含上次更新已更改的员工的新列表? 我只能想到迭代列表和比较,可能最终几乎是O(n2)时间,这可以由任何util类更有效地完成吗?
问题内容: 我想检查两个结构,切片和映射是否相等。 但是我遇到了以下代码的问题。在相关行中查看我的评论。 http://play.golang.org/p/AZIzW2WunI 问题答案: 您可以使用reflect.DeepEqual,也可以实现自己的函数(在性能上比使用反射更好): http://play.golang.org/p/CPdfsYGNy_
我有一个脚本,可以将文件从一个文件夹结构复制到另一个具有不同结构的文件夹。 脚本以这种格式将文件/目录从文件夹1复制到文件夹2(文件夹2具有不同的结构) 在文件夹2中,我可以创建自己的文件,如new1。txt,new2。txt。创建新文件后,文件夹2的结构如下: 现在我需要比较Folder1和Folder2的目录内容。我正在使用filecmp。用于比较目录内容的dircmp。filecmp。这两个
问题内容: 有没有人在编写比较两个REST服务的测试方面有任何技巧?我们这样做是作为回归测试的一种形式。 我希望按照以下方式做一些事情: 向两个服务发送“ / 1”的GET并比较结果 向这两个服务发送POST,然后比较结果 向两个服务发送一个PUT,并比较结果 这个想法是: 每个操作都发送到两个服务 结果应该相同 REST服务是用Java / Jersey编写的,因此使用它是理想的,但是人们发现有
问题内容: 我有两个边界框的两个坐标,其中一个是地面坐标,另一个是我工作的结果。我想根据地雷来评估我的准确性。所以我问是否有人有任何建议 边框详细信息以这种格式保存 问题答案: 编辑:我已更正其他用户指出的错误。 我假设您正在检测某些对象,并且正在围绕它绘制一个边界框。这属于对象检测的广泛研究/研究领域。评估精度的最佳方法是计算并集交集。这是从PASCAL VOC挑战中获得的,这里。请参阅此处的视