验证一个文件中给定的 JSON 键和值在另一个文件中是否可用的最佳方法

Best way of validating if a given JSON key and value in one file is available in another file

我发现很难实现一种逻辑来检查一个文件中的某个键值(一起)是否在另一个文件中具有实际完全相似的键值

我有一个文件如下,

[
{
"IdInOne": "001",
"NameInOne": "Name_2"
},
{
"IdInOne": "002",
"NameInOne": "Name_3"
}
]

另一个为

[
{
"IdInTwo": "001",
"NameInTwo": "Name_1"
},
{
"IdInTwo": "001",
"NameInTwo": "Name_2"
},
{
"IdInTwo": "001",
"NameInTwo": "Name_3"
},
{
"IdInTwo": "002",
"NameInTwo": "Name_4"
}
]

在此示例中,有一个条目 "IdInOne": "001","NameInOne": "Name_2" 与第二个 JSON 文件中的完全相同的值匹配。所以在那种情况下,我将打印一条成功消息

但在第二个 JSON 文件中没有匹配项 "IdInOne": "002","NameInOne": "Name_3" 因此我想在控制台中打印一个不成功的消息

谁能帮我解决这个问题?知道我需要什么样的算法吗?

使用 Newtonsoft 并使用 POCO class 解析您的两个模型,然后比较两个实例的属性。

请参阅此示例,了解如何反序列化 json

https://www.newtonsoft.com/json/help/html/DeserializeObject.htm

您可以使用反射来迭代第二个对象的所有属性,要求 属性 的值进行比较。 当您不知道要与之比较的 属性 的名称时,这很有用。

希望对您有所帮助

您可以先制作两个模型 类 代表您的 JSON:

public class One
{
    public string IdInOne { get; set; }
    public string NameInOne { get; set; }
}

public class Two
{
    public string IdInTwo { get; set; }
    public string NameInTwo { get; set; }
}

然后使用 Newtonsoft Json.NET 将 JSON 与这些 类 反序列化。由于我们正在处理 JSON 数组,因此我们可以反序列化为 List<T>

var json1 = "[{\"IdInOne\": \"001\",\"NameInOne\": \"Name_2\"},{\"IdInOne\": \"002\",\"NameInOne\": \"Name_3\"}]";
var json2 = "[{\"IdInTwo\": \"001\",\"NameInTwo\": \"Name_1\"},{\"IdInTwo\": \"001\",\"NameInTwo\": \"Name_2\"},{\"IdInTwo\": \"001\",\"NameInTwo\": \"Name_3\"},{\"IdInTwo\": \"002\",\"NameInTwo\": \"Name_4\"}]";

var deserializedJson1 = JsonConvert.DeserializeObject<List<One>>(json1);
var deserializedJson2 = JsonConvert.DeserializeObject<List<Two>>(json2);

然后您可以简单地使用 LINQ 中的 Any() 进行比较:

foreach (var one in deserializedJson1)
{
    if (deserializedJson2.Any(two => two.IdInTwo == one.IdInOne &&
                              two.NameInTwo == one.NameInOne))
    {
        Console.WriteLine($"Match found with {one.IdInOne} and {one.NameInOne}");
    } else
    {
        Console.WriteLine($"No match found with {one.IdInOne} and {one.NameInOne}");
    }
}

哪些输出:

Match found with 001 and Name_2
No match found with 002 and Name_3

另一种实现可能是反序列化为元组,然后简单地将 twos 转换为 HashSet<T> 并将其用于查找。拥有哈希集可以将查找从 O(N) 改进为 O(1),并且可以为更大的数据集提供性能提升。 HashSet<T>.Contains(T) 是一个 O(1) 方法。

var ones = JsonConvert
    .DeserializeObject<List<One>>(json1)
    .Select(x => (x.IdInOne, x.NameInOne));

var lookups = JsonConvert
    .DeserializeObject<List<Two>>(json2)
    .Select(x => (x.IdInTwo, x.NameInTwo))
    .ToHashSet();

foreach (var (IdInOne, NameInOne) in ones)
{
    if (lookups.Contains((IdInOne, NameInOne)))
    {
        Console.WriteLine($"Match found with {IdInOne} and {NameInOne}");
    } else
    {
        Console.WriteLine($"No match found with {IdInOne} and {NameInOne}");
    }
}