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

如何在Dictionary中处理重复键生成逗号分隔字符串?求替代方案

按键合并键值对的最优实现方案

我有一个List<string>类型的输入数据,每个元素是用&分隔的多组键值对筛选条件。需要把这些键值对按键归类,当键重复时,把对应的值合并成带括号的逗号分隔字符串。想知道实现这个需求的最优方式是什么?有没有Dictionary<string, string>的替代方案?有的话愿意尝试。

当前代码在键已存在时会报错,没法生成目标格式。以下是输入、预期输出和当前代码示例:

输入:

var input = new List<string>
{
    "Location=COL&StockNumber=1111150416",
    "Location=NYC&StockNumber=2222250416&Invoice=Part",
    "Location=NYC&StockNumber=2222250416&Invoice=Part&Supplier=AutoZone"
};

预期输出:

var output = new Dictionary<string, string>
{
    { "Location", "(COL, NYC)" },
    { "StockNumber", "(1111150416, 2222250416, 2222250417)" },
    { "Invoice", "(Part)" },
    { "Supplier", "(AutoZone)" }
};

当前问题:

  • 键已存在时,当前代码会抛出错误,无法生成带括号的逗号分隔值格式

当前代码:

var testDictionary = new Dictionary<string, string>();
for(var i = 0; i < keys.Count; i++) {
    var items = keys[i].Split("&");

    for (var j = 0; j < items.Length; j++)
    {
        var data = items[j].Split("=");
        if (testDictionary.ContainsKey(data[0]))
         {
            testDictionary[data[0]] = // 不知道怎么在这里添加逗号分隔的值
         }
        testDictionary.Add(data[0], data[1]);
    }
}

一、改进Dictionary<string, string>实现

当前代码的核心问题是直接调用Add方法,忽略了键已存在的情况。正确思路是先收集同键的所有值(可选去重),最后再统一格式化为带括号的字符串。

示例代码:

// 先用Dictionary存每个键对应的所有值(HashSet自动去重)
var tempDict = new Dictionary<string, HashSet<string>>();

foreach (var line in input)
{
    var keyValuePairs = line.Split('&');
    foreach (var kvp in keyValuePairs)
    {
        var parts = kvp.Split('=');
        if (parts.Length != 2) continue; // 跳过格式无效的键值对
        var key = parts[0];
        var value = parts[1];

        if (!tempDict.ContainsKey(key))
        {
            tempDict[key] = new HashSet<string>();
        }
        tempDict[key].Add(value);
    }
}

// 转换为最终需要的格式
var output = tempDict.ToDictionary(
    kv => kv.Key,
    kv => $"({string.Join(", ", kv.Value)})"
);

优点:

  • 用HashSet自动去重,避免同一个键下出现重复值
  • 分步处理逻辑清晰,容错性强(能跳过无效格式的键值对)
  • 手动控制集合操作,灵活性高

二、替代方案:使用Lookup<string, string>

.NET原生的Lookup<TKey, TElement>是专门为一键多值场景设计的集合类型,比手动用Dictionary存集合更简洁高效。

示例代码:

// 扁平化所有有效键值对
var allValidKvp = input.SelectMany(line => 
    line.Split('&').Select(kvp => 
    {
        var parts = kvp.Split('=');
        return parts.Length == 2 ? (Key: parts[0], Value: parts[1]) : default;
    })
).Where(kvp => kvp.Key != null);

// 创建Lookup分组
var lookup = allValidKvp.ToLookup(kvp => kvp.Key, kvp => kvp.Value);

// 转换为目标格式
var output = lookup.ToDictionary(
    group => group.Key,
    group => $"({string.Join(", ", group.Distinct())})"
);

优点:

  • 原生支持一键多值分组,代码更简洁
  • 内部实现经过优化,分组效率更高
  • 只读特性避免意外修改,适合数据分组场景

三、性能与场景选择

  • 如果需要频繁修改分组数据,优先选Dictionary<HashSet<string>>,灵活性更强
  • 如果是一次性分组需求,Lookup的代码更简洁,性能表现更稳定
  • 若不需要去重,可以把HashSet换成List<string>,或去掉Distinct(),进一步提升性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:37:49