使用 C# 在复杂的 JSON 数组中查找和打印重复项
Posted
技术标签:
【中文标题】使用 C# 在复杂的 JSON 数组中查找和打印重复项【英文标题】:Find and print duplicates in a complex JSON array using C# 【发布时间】:2021-04-29 13:13:15 【问题描述】:我正在尝试使用 .NET 中的 C# 从复杂的嵌套 JSON 数组中找出并打印重复项。
我想检查值 "title" 是否重复,并且还有一个嵌套的 JSON 数组 (items) 具有以下值:title 和 value 我要检查其中的重复项。
因此,嵌套数组的 title 和 value 值应与其他嵌套数组值的值进行比较。 外部的“标题”应与外部的检查。
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,这些项目是否在数组中? 另外,你期待什么输出?以上3项根据你的描述都是不一样的吧? @DavidG 这是一个复杂 JSON 数组的示例,只是为了说明它的外观。如果有重复的值,我想打印它们。 @DavidG 如果它有助于类似的事情可能是这个i.stack.imgur.com/JXV19.png 你在哪里解决问题? 【参考方案1】:一种方法是将上述 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);
【讨论】:
你能检查一下这个有在线编辑器的链接吗? dotnetfiddle.net/sln3wH 你想让我用那个链接做什么? 是在线编辑器.net fiddle,我试图解决我在这篇文章中描述的问题。通过阅读可能会更好地理解我的观点。以上是关于使用 C# 在复杂的 JSON 数组中查找和打印重复项的主要内容,如果未能解决你的问题,请参考以下文章
在 C# 中绘制和打印复杂文档(改进/替换我的 PrintDocument)