gpt4 book ai didi

c# - 模糊深度对象比较

转载 作者:行者123 更新时间:2023-11-30 12:28:18 24 4
gpt4 key购买 nike

我有一个方法可以返回一个包含很多字段的巨大对象。像这样:

{
Success: true,
Timestamp: "07.03.2014",
Items:
[
{
Name: "A",
Price: 13.37,
OtherData: 123
},
{
Name: "B",
Price: 42,
OtherData: 312
}
]
}

我想将其返回值与 .NET 应用程序中测试的引用值进行比较。但是,这里有几个问题:

  • Timestamp 字段每次都会改变
  • Price 字段中的舍入也可能不同
  • Items 的顺序并不重要

我想以最灵活的方式定义一个引用对象:

  • 省略不必要的字段
  • 不仅能够指定值,还能指定规则(字符串的正则表达式、数字的范围/舍入等)

下面是引用定义的示例:

{
Success: true,
Items:
[
{
Name: "A",
Price: "13.37",
},
{
Name: "B",
Price: 42,
}
]
}

是否有任何类型的 .NET 库可以进行此类比较?

最佳答案

最后我决定自己实现比较。这是代码,也许它会对某人有用:

public static class Utils
{
public static bool SequencesMatch<TSource, TPattern>(IEnumerable<TSource> sequence, IEnumerable<TPattern> patterns, Func<TSource, TPattern, bool> matcher)
{
var items = sequence.Select(x => new SequenceItem<TSource>(x)).ToArray();
var pats = patterns.Select(x => new SequenceItem<TPattern>(x)).ToArray();

foreach (var item in items)
{
foreach (var pat in pats)
{
if (pat.Matched) continue;
if (matcher(item.Value, pat.Value))
{
item.Matched = pat.Matched = true;
break;
}
}
}

return items.All(x => x.Matched) && pats.All(x => x.Matched);
}

public static bool JsonObjectsMatch(JToken data, JToken reference)
{
if (reference.Type == JTokenType.Array)
return SequencesMatch(data, reference, JsonObjectsMatch);

if (reference.Type == JTokenType.Object)
{
var dataObj = data as JObject;
var refObj = reference as JObject;

if (dataObj == null || refObj == null)
Assert.Fail("DataObject = '{0}', ReferenceObject = '{1}'", dataObj, refObj);

foreach (var pty in refObj)
{
var dataValue = dataObj[pty.Key];
if (dataValue == null || !JsonObjectsMatch(dataValue, pty.Value))
Assert.Fail("Objects differ at {0}: DataValue = '{1}', RefValue = '{2}'", pty.Key, dataValue, pty.Value);
}

return true;
}

if (reference.Type == JTokenType.Float)
{
var refFloat = reference.ToObject<float>();
var dataFloat = data.ToObject<float>();

if(Math.Abs(dataFloat - refFloat) > 0.001)
Assert.Fail("Objects differ: DataValue = '{0}', RefValue = '{1}'", dataFloat, refFloat);

return true;
}

return JToken.DeepEquals(data, reference);
}

private class SequenceItem<T>
{
public T Value { get; set; }
public bool Matched { get; set; }

public SequenceItem(T value)
{
Value = value;
}
}
}

一旦我有足够的时间,我可能应该把它变成一个合适的库并在 GitHub 上发布。

关于c# - 模糊深度对象比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22243661/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com