C#中如何优雅实现带分隔符字符串的递进式前缀拆分?
嘿,这个需求我之前做配置解析的时候也碰到过!你的现有实现逻辑完全没问题,可读性也很好,但确实有几种更简洁优雅的写法,分享给你:
1. 用LINQ Aggregate(兼容所有.NET版本)
Aggregate天生适合这种逐步累积的场景,一行LINQ就能搞定:
var myString = "a.b.c.d"; var fieldSeparator = '.'; var fieldNames = myString.Split(fieldSeparator) .Aggregate(new List<string>(), (accumulatedList, currentField) => { var nextPrefix = accumulatedList.Any() ? $"{accumulatedList.Last()}{fieldSeparator}{currentField}" : currentField; accumulatedList.Add(nextPrefix); return accumulatedList; });
它的逻辑和你原来的循环完全一致,只是用LINQ的方式封装了起来,代码更紧凑。
2. 用LINQ Scan(.NET 6+ 专属简洁写法)
如果你用的是.NET 6或更高版本,Scan方法会更省心——它专门用来返回Aggregate过程中的每一步中间结果,完美匹配我们的需求:
var myString = "a.b.c.d"; var fieldSeparator = '.'; var fieldNames = myString.Split(fieldSeparator) .Scan((previousPrefix, currentField) => $"{previousPrefix}{fieldSeparator}{currentField}") .ToList();
这段代码几乎是“自解释”的:把拆分后的每个字段,和前一个前缀拼接成新的前缀,最后把所有前缀收集成列表,极简!
3. 高性能方案:用Span减少字符串分配
如果你的字符串很长,或者需要处理大量这类字符串,上面的方法会有不少字符串拼接的内存分配。用Span<char>直接截取原字符串的片段,能大幅减少内存开销:
var myString = "a.b.c.d"; var fieldSeparator = '.'; var fieldNames = new List<string>(); int lastSplitIndex = 0; for (int i = 0; i < myString.Length; i++) { if (myString[i] == fieldSeparator) { // 直接截取从lastSplitIndex到当前i的片段,避免拼接 fieldNames.Add(myString[lastSplitIndex..i]); lastSplitIndex = i + 1; } } // 添加最后一个完整前缀 fieldNames.Add(myString[lastSplitIndex..]);
这个方法不需要先拆分整个字符串,而是一边遍历一边截取,内存效率拉满。
其实你原来的写法已经很清晰了,这些方案只是在不同场景下提供更优雅的选择——如果追求兼容性选Aggregate,追求代码简洁选Scan,追求性能选Span~
内容的提问来源于stack exchange,提问作者tryurbest
相关产品推荐
相关产品推荐

