在C# 6.0/.Net Framework 4.8中实现类SQL STRING_SPLIT的带序号拆分
实现带序号的字符串拆分并关联保留顺序
1. 拆分字符串并生成带序号的集合
直接用Split拆分字符串,再通过Select的带索引重载生成从1开始的序号,完全保留原字符串的元素顺序:
string input = "abc,xyz,def,tuv"; // 拆分后生成带序号的集合,序号从1起始 var splitWithOrdinal = input.Split(',') .Select((item, index) => (Ordinal: index + 1, Value: item));
如果要处理元素前后的空格(比如输入是"abc, xyz"),可以给每个元素加Trim():
var splitWithOrdinal = input.Split(',') .Select((item, index) => (Ordinal: index + 1, Value: item.Trim()));
2. 与无序列表关联并保留原顺序
假设你有一个无序列表,需要筛选出拆分集合中存在于该列表的元素,同时严格保持原字符串的顺序:
// 示例无序列表 var targetItems = new List<string> { "tuv", "abc" }; // 转成HashSet提升查询性能(元素数量多的时候效果明显) var targetSet = new HashSet<string>(targetItems); // 筛选后直接保留原顺序 var result = splitWithOrdinal .Where(item => targetSet.Contains(item.Value)) .ToList();
执行后result的结果就是:(1, "abc")、(4, "tuv"),完全匹配需求。
3. 封装成扩展方法(可选)
如果需要重复使用这个拆分逻辑,可以封装成字符串的扩展方法:
public static class StringExtensions { public static IEnumerable<(int Ordinal, string Value)> SplitWithOrdinal(this string input, char separator) { if (string.IsNullOrWhiteSpace(input)) yield break; foreach (var (item, index) in input.Split(separator).Select((item, idx) => (item, idx))) { yield return (Ordinal: index + 1, Value: item.Trim()); } } }
使用时更简洁:
var input = "abc,xyz,def,tuv"; var splitData = input.SplitWithOrdinal(','); var targetSet = new HashSet<string> { "tuv", "abc" }; var result = splitData.Where(item => targetSet.Contains(item.Value)).ToList();
顺序保障说明
Split返回的数组严格遵循原字符串的元素顺序;Select的带索引重载按数组遍历顺序生成序号,不会打乱顺序;Where仅过滤元素,不会改变剩余元素的相对顺序;- 即使使用
Join关联,结果也会保持左侧拆分集合的顺序:
var result = splitWithOrdinal.Join(targetItems, splitItem => splitItem.Value, targetItem => targetItem, (splitItem, _) => (splitItem.Ordinal, splitItem.Value)) .ToList();
内容的提问来源于stack exchange,提问作者pmbAustin
相关产品推荐
相关产品推荐

