C#使用字典处理重复订单ID 统计指定订单商品数与总金额
需求说明
需要从指定格式的订单文本中,统计订单ID为1211、4322的总商品数、总金额,要求使用支持重复键存储的字典结构存取数据,最终输出格式参考:OrderId:1211 Order Name=Alice, Total Id=2, Total Price=45000
原始订单数据源如下:
OrderID=1211, OrderName=’Alice’, OrderDate= ‘15-10-2019’ //- row1 OrderID=1211, ItemID=1, ItemName=’Laptop’, ItemCompany=’Dell’, ItemPrice=’40000’ //row2 OrderID=1211, ItemID=2, ItemName=’Mouse’, ItemCompany=’Logitech’, ItemPrice=’5000’ //3 OrderID=4322, OrderName=’Ben’, OrderDate= ‘1-10-2019’//4 OrderID=4322, ItemID=1, ItemName=’Laptop’, ItemCompany=’Microsoft’, ItemPrice=’40000’//5 OrderID=4322, ItemID=2, ItemName= ‘Keyboard’, ItemCompany=’Microsoft’, ItemPrice=’12000’ //6
原有代码问题
- 普通
Dictionary<TKey,TValue>本身不支持重复键存入,重复调用Add方法传入相同键会直接抛出异常 - 行拆分逻辑没有过滤行尾注释、字段值里的多余引号和空格,解析结果不准确
- 没有区分订单基础信息行和商品明细行,键值存储逻辑混乱,无法支撑后续统计计算
实现方案
- 严格满足可存储重复键的要求,使用
List<KeyValuePair<string, Dictionary<string,string>>>作为类字典结构,允许同一个OrderID作为键重复存储多行数据 - 逐行读取时先截掉
//后的注释内容,再按逗号拆分每个键值对,清理掉字段值里的单引号、前后无效空格 - 所有行存入重复键字典后,遍历字典按OrderID聚合数据:记录订单对应的用户名,累计商品数量、商品总金额
- 最后按要求格式输出统计结果
完整实现代码
using System; using System.Collections.Generic; using System.IO; class OrderStat { public string OrderName { get; set; } public int TotalItemCount { get; set; } public int TotalPrice { get; set; } } class Program { static void Main(string[] args) { // 支持重复键的字典结构:键为OrderID,值为当前行解析出的所有字段键值对 List<KeyValuePair<string, Dictionary<string, string>>> repeatKeyDict = new List<KeyValuePair<string, Dictionary<string, string>>>(); // 替换为你本地的实际文件路径,原代码路径缺少\\分隔符会导致读取失败 using (StreamReader sr = new StreamReader(@"c:\Probb.txt")) { string line; while ((line = sr.ReadLine()) != null) { // 移除行尾注释内容 if (line.Contains("//")) line = line.Substring(0, line.IndexOf("//")); if (string.IsNullOrWhiteSpace(line)) continue; Dictionary<string, string> fieldDict = new Dictionary<string, string>(); string[] fieldPairs = line.Split(',', StringSplitOptions.RemoveEmptyEntries); string currentOrderId = string.Empty; foreach (string pair in fieldPairs) { string[] kv = pair.Split('=', StringSplitOptions.RemoveEmptyEntries); if (kv.Length != 2) continue; string key = kv[0].Trim(); // 清理值内容里的单引号、前后空格 string value = kv[1].Trim().Trim('’', '‘', '\''); fieldDict[key] = value; if (key == "OrderID") currentOrderId = value; } if (!string.IsNullOrEmpty(currentOrderId)) { // 存入重复键字典,同一个OrderID可多次添加 repeatKeyDict.Add(new KeyValuePair<string, Dictionary<string, string>>(currentOrderId, fieldDict)); } } } // 从重复键字典中聚合统计结果 Dictionary<string, OrderStat> statResult = new Dictionary<string, OrderStat>(); foreach (var row in repeatKeyDict) { string orderId = row.Key; var fields = row.Value; if (!statResult.ContainsKey(orderId)) statResult[orderId] = new OrderStat(); // 匹配到订单基础信息行,记录用户名 if (fields.ContainsKey("OrderName")) { statResult[orderId].OrderName = fields["OrderName"]; } // 匹配到商品明细行,累计商品数和总金额 if (fields.ContainsKey("ItemPrice")) { statResult[orderId].TotalItemCount += 1; statResult[orderId].TotalPrice += int.Parse(fields["ItemPrice"]); } } // 按指定格式输出 foreach (var stat in statResult) { Console.WriteLine($"OrderId:{stat.Key} Order Name={stat.Value.OrderName}, Total Id={stat.Value.TotalItemCount}, Total Price={stat.Value.TotalPrice}"); } Console.ReadKey(); } }
运行输出结果
OrderId:1211 Order Name=Alice, Total Id=2, Total Price=45000 OrderId:4322 Order Name=Ben, Total Id=2, Total Price=52000
内容的提问来源于stack exchange,提问作者John_Martin
相关产品推荐
相关产品推荐

