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

C#中无需遍历筛选ConcurrentDictionary内List<T>指定产品类型项

Question

我需要筛选ConcurrentDictionary<string, List<PAAMsg>>中的数据,忽略产品类型不在指定字符串“BFO,BFT,BOND FWD,CAP,FEE,FEX,FRA,FUT,FxFUT,MFO,SWP,OFT,SWT”内的List<PAAMsg>项。目前已通过foreach循环实现该需求,但希望无需遍历,用单行代码完成,是否有可行方案?

当前实现代码如下:

private ConcurrentDictionary<string, List<PAAMsg>> FilterAllowedProductsTrades(ConcurrentDictionary<string, List<PAAMsg>> allPAA) {
    ConcurrentDictionary<string, List<PAAMsg>> newPAA = new ConcurrentDictionary<string, List<PAAMsg>>();
    string productType = "BFO,BFT,BOND FWD,CAP,FEE,FEX,FRA,FUT,FxFUT,MFO,SWP,OFT,SWT";
    foreach (var item in allPAA) {
        newPAA.TryAdd(
            item.Key,
            item.Value.FindAll((x => productType.Split(',').Contains(x.ProductType)))
            .ToList());
    }
    return newPAA;
}
Answer

当然可以实现简洁的LINQ写法!不过先给你提个关键的性能优化点——你原来的代码里每次FindAll都调用productType.Split(','),这会反复生成新数组,数据量大的时候性能损耗特别明显,建议提前把允许的产品类型转成HashSet<string>,查找时间复杂度直接从O(n)降到O(1)。

下面是优化后的简洁实现(兼顾可读性和性能):

private ConcurrentDictionary<string, List<PAAMsg>> FilterAllowedProductsTrades(ConcurrentDictionary<string, List<PAAMsg>> allPAA)
{
    var allowedProductTypes = new HashSet<string> { "BFO", "BFT", "BOND FWD", "CAP", "FEE", "FEX", "FRA", "FUT", "FxFUT", "MFO", "SWP", "OFT", "SWT" };
    return new ConcurrentDictionary<string, List<PAAMsg>>(
        allPAA.ToDictionary(
            kvp => kvp.Key,
            kvp => kvp.Value.Where(msg => allowedProductTypes.Contains(msg.ProductType)).ToList()
        )
    );
}

如果你真的要极致压缩成一行(不推荐,可读性会大打折扣),可以写成这样:

private ConcurrentDictionary<string, List<PAAMsg>> FilterAllowedProductsTrades(ConcurrentDictionary<string, List<PAAMsg>> allPAA) => new ConcurrentDictionary<string, List<PAAMsg>>(allPAA.ToDictionary(k => k.Key, v => v.Value.Where(m => new HashSet<string> { "BFO", "BFT", "BOND FWD", "CAP", "FEE", "FEX", "FRA", "FUT", "FxFUT", "MFO", "SWP", "OFT", "SWT" }.Contains(m.ProductType)).ToList()));

补充说明:

  • 我们用ToDictionary先把原ConcurrentDictionary的键值对转换成普通字典,再直接传入ConcurrentDictionary的构造函数,省去了手动遍历调用TryAdd的过程。
  • 要是你的场景是多线程同时操作这个字典也不用担心:LINQ的ToDictionary是单线程执行的,构造ConcurrentDictionary的过程也是线程安全的,后续对新字典的操作依然能保持线程安全特性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:49:04