c# - 使用 C# 在复杂的 JSON 数组中查找和打印重复项
问题描述
我试图在 .NET 中使用 C# 从复杂的嵌套 JSON 数组中找出并打印重复项。
我想检查值“title”是否重复,并且还有一个嵌套的 JSON 数组(项目),其中包含以下值:我要检查重复项的标题和值。
因此,嵌套数组的值:标题和值应与其他嵌套数组值的值进行比较。外部“标题”应与外部“标题”核对。
id 和 sourceId 应该被忽略
尝试使用 foreach 执行此操作,但无法使用 . (点)。然后尝试使用 for 循环,但我迷路了。
结果,我想打印重复的值。
你可以帮帮我吗?
JSON数组的外观概述如下
{
"id": "0789a960-45de-11ea-ae56-23ecd3bd0e35",
"sourceId": "6e009cc0-fc83-11e9-8fb9-01af70ec8d3f",
"title": "Glass-reinforced concrete (GRC) built-in quoins",
"items": [{
"title": "Description",
"value": ""
}, {
"title": "Manufacturer",
"value": ""
}, {
"title": "Height (overall)",
"value": ""
}, {
"title": "Applied surface finish",
"value": ""
}, {
"title": "Applied finish colour",
"value": ""
}]
}, {
"id": "0a607010-45de-11ea-ae56-23ecd3bd0e35",
"sourceId": "73a96f31-fc83-11e9-8fb9-01af70ec8d3f",
"title": "Clay bricks",
"items": [{
"title": "Description",
"value": ""
}, {
"title": "Manufacturer",
"value": ""
}, {
"title": "Standard",
"value": ""
}, {
"title": "Brick description",
"value": ""
}, {
"title": "Execution",
"value": ""
}]
}, {
"id": "0ce40db0-45de-11ea-ae56-23ecd3bd0e35",
"sourceId": "73a96f31-fc83-11e9-8fb9-01af70ec8d3f",
"title": "Clay bricks",
"items": [{
"title": "Description",
"value": ""
}, {
"title": "Manufacturer",
"value": ""
}, {
"title": "Standard",
"value": ""
}, {
"title": "Appearance",
"value": ""
}, {
"title": "Execution",
"value": ""
}]
}, ............. and so on
解决方案
一种方法是将上述 JSON 转换为 C# 对象以保存您要反序列化的属性,例如:
public class Thing
{
public string Title { get; set; }
public List<TitleValue> Items { get; set; }
}
public class TitleValue
{
public string Title { get; set; }
public string Value { get; set; }
// This is needed later for the comparer
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 31 + Title.GetHashCode();
hash = hash * 31 + Value.GetHashCode();
return hash;
}
}
}
现在您可以反序列化成这样的项目列表:
// If you are using Newtonsoft JSON.Net:
var things = JsonConvert.DeserializeObject<List<Thing>>(jsonString);
// If you are using System.Text.Json:
var settings = new System.Text.Json.JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var things = JsonSerializer.Deserialize<List<Thing>>(jsonString, settings);
您可以制作的下一件事是实现IEqualityComparer<Thing>
您可以传递给 Linq的类GroupBy
。例如:
public class ThingEqualityComparer : IEqualityComparer<Thing>
{
public bool Equals(Thing x, Thing y)
{
if (!x.Title.Equals(y.Title))
return false;
if (x.Items.Count() != y.Items.Count())
return false;
foreach (var item in x.Items)
{
if (!y.Items.Any(otherItem => otherItem.Title.Equals(item.Title) &&
otherItem.Value.Equals(item.Value)))
return false;
}
return true;
}
public int GetHashCode(Thing obj)
{
unchecked
{
int hash = 17;
hash = hash * 31 + obj.Title.GetHashCode();
foreach (var item in obj.Items)
{
hash = hash * 31 + item.GetHashCode();
}
return hash;
}
}
}
现在您可以运行一些 Linq 查询,例如:
var thingCounts = things
.GroupBy(t => t, new ThingEqualityComparer())
.Select(g => new
{
Thing = g.Key,
Count = g.Count()
});
如果您想在该列表中查找重复项,可以使用Where
子句过滤它们:
var duplicateThingCounts = thingCounts.Where(tc => tc.Count > 1)
现在您可以对重复项做任何您想做的事情,例如打印出您喜欢的任何内容:
foreach (var thingCount in duplicateThingCounts)
{
Console.WriteLine(thingCount.Thing.Title);
}
推荐阅读
- keras - ValueError:检查输入时出错:预期的 dense_1_input 有 2 个维度
- openldap - 如何在 python-ldap 中加密(MD5)密码?
- python - 编写全局配置文件的正确方法是什么?
- c# - 如何修复报告 RDLC 在没有 Visual Studio 的情况下无法在 IIS 上运行?
- mongodb - Studio 3T 工具:避免在每次查询运行时出现新的控制台输出选项卡
- java - 在数组中找到不重复的对,加起来等于给定的总和
- linux - 在 Windows 和 Linux 上的 Dockerfile 中使用 RUN 命令
- rust - 从宏规则返回值!在锈
- python-docx - python-docx:document.tables 中缺少表
- git - 从 github-plugin 完全重命名提交状态的默认上下文