验证一个文件中给定的 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}");
}
}
我发现很难实现一种逻辑来检查一个文件中的某个键值(一起)是否在另一个文件中具有实际完全相似的键值
我有一个文件如下,
[
{
"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}");
}
}