You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中查找JSON数组中的重复对象并统计出现次数

解决C#中大型JSON数组重复对象统计的问题

嘿,作为C#新手碰到这个需求完全正常,我来给你捋清楚解决思路和具体实现步骤~

核心思路拆解

要完成这个任务,我们需要三步:

  • 把JSON字符串转换成C#的强类型对象(方便操作,比硬解析字符串靠谱多了)
  • 基于对象的所有属性进行分组,统计每组的出现次数
  • 把分组后的结果转换成你需要的输出格式,再序列化回JSON

第一步:定义匹配JSON结构的C#实体类

首先我们要创建和JSON结构对应的类,这样反序列化后能直接用对象操作:

// 对应数组里的单个数据对象
public class DataItem
{
    public string date { get; set; }
    public string someID { get; set; }
    public string someType1 { get; set; }
    public string someType2 { get; set; }
}

// 对应最外层的原始JSON结构
public class RootObject
{
    public List<DataItem> data { get; set; }
}

// 对应最终输出的单条结果(继承DataItem,新增统计属性)
public class ResultItem : DataItem
{
    public int objCount { get; set; }
}

// 对应最终输出的外层结构
public class ResultRoot
{
    public List<ResultItem> result { get; set; }
}

第二步:反序列化JSON + 分组统计

这里我们用**Json.NET(Newtonsoft.Json)**来处理JSON(这是C#里最常用的JSON库,新手可以先从这个入手;如果用的是.NET 5+,也可以用自带的System.Text.Json,用法类似)。

首先你需要通过NuGet安装Newtonsoft.Json包,然后写代码:

using Newtonsoft.Json;
using System.Linq;

// 你的原始JSON字符串
string originalJson = @"{""data"": [ { ""date"": ""20220101"", ""someID"": ""ID1"", ""someType1"": ""SRVC"", ""someType2"": ""SEND"" }, { ""date"": ""20220101"", ""someID"": ""ID1"", ""someType1"": ""SRVC"", ""someType2"": ""SEND"" }, { ""date"": ""20220101"", ""someID"": ""ID2"", ""someType1"": ""SRVC"", ""someType2"": ""RECV"" }, { ""date"": ""20220101"", ""someID"": ""ID2"", ""someType1"": ""SRVC"", ""someType2"": ""RECV"" }, { ""date"": ""20220101"", ""someID"": ""ID2"", ""someType1"": ""SRVC"", ""someType2"": ""RECV"" }, { ""date"": ""20220101"", ""someID"": ""ID2"", ""someType1"": ""SRVC"", ""someType2"": ""SEND"" }, { ""date"": ""20220101"", ""someID"": ""ID2"", ""someType1"": ""SRVC"", ""someType2"": ""SEND"" }, { ""date"": ""20220101"", ""someID"": ""ID2"", ""someType1"": ""SRVC"", ""someType2"": ""SEND"" } ] }";

// 1. 把JSON字符串反序列化成C#对象
var root = JsonConvert.DeserializeObject<RootObject>(originalJson);

// 2. 用LINQ分组统计:以对象的所有属性作为分组键,自动归类重复对象
var groupedItems = root.data
    .GroupBy(item => new { item.date, item.someID, item.someType1, item.someType2 })
    .Select(group => new ResultItem
    {
        date = group.Key.date,
        someID = group.Key.someID,
        someType1 = group.Key.someType1,
        someType2 = group.Key.someType2,
        objCount = group.Count()
    })
    .ToList();

// 3. 组装成你需要的输出结构
var resultRoot = new ResultRoot { result = groupedItems };

// 4. 把结果序列化回格式化后的JSON字符串
string outputJson = JsonConvert.SerializeObject(resultRoot, Formatting.Indented);
Console.WriteLine(outputJson);

关键细节说明

  • 为什么用匿名类型作为分组键? 匿名类型的Equals和GetHashCode方法会自动基于所有属性的值生成,只要两个对象的四个属性完全相同,就会被分到同一组,完美匹配我们判断"重复对象"的需求。
  • 超大型数组的优化方案:如果你的JSON数组特别大(比如几十万条以上),LINQ的GroupBy可能会占用较多内存。这时候可以手动用Dictionary来统计,内存占用更可控:
var countDict = new Dictionary<object, int>();
foreach (var item in root.data)
{
    var key = new { item.date, item.someID, item.someType1, item.someType2 };
    if (countDict.ContainsKey(key))
        countDict[key]++;
    else
        countDict[key] = 1;
}

// 把字典转换成ResultItem列表
var resultItems = countDict.Select(kv => new ResultItem
{
    date = kv.Key.date,
    someID = kv.Key.someID,
    someType1 = kv.Key.someType1,
    someType2 = kv.Key.someType2,
    objCount = kv.Value
}).ToList();

.NET 5+ 自带System.Text.Json的替代方案

如果你用的是较新的.NET版本,不想额外装NuGet包,可以用自带的System.Text.Json,写法类似:

using System.Text.Json;

// 反序列化
var root = JsonSerializer.Deserialize<RootObject>(originalJson);

// 分组统计(逻辑和之前完全一致)
var groupedItems = root.data
    .GroupBy(item => new { item.date, item.someID, item.someType1, item.someType2 })
    .Select(group => new ResultItem
    {
        date = group.Key.date,
        someID = group.Key.someID,
        someType1 = group.Key.someType1,
        someType2 = group.Key.someType2,
        objCount = group.Count()
    })
    .ToList();

// 序列化回格式化后的JSON
var options = new JsonSerializerOptions { WriteIndented = true };
string outputJson = JsonSerializer.Serialize(new ResultRoot { result = groupedItems }, options);
Console.WriteLine(outputJson);

运行后就能得到你想要的输出结果啦!如果有其他细节问题,随时问~

内容的提问来源于stack exchange,提问作者Jonald Monday

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 12:07:33