如何在集合For循环内查找字符串模式索引?Linq高效实现及区间捕获
解决方案:捕获Billing Address到Shipping Address之间的行
传统For循环实现
如果你想在单次遍历中完成标记检测与内容捕获,可以通过状态标记的方式实现,逻辑直观且效率较高:
List<string> billingLines = new List<string>(); bool isCapturing = false; for (int i = 0; i < lines.Count; i++) { string currentLine = lines[i].Trim(); // 触发捕获起始 if (currentLine.Equals("Billing Address", StringComparison.OrdinalIgnoreCase)) { isCapturing = true; continue; // 可根据需求决定是否包含标记行本身 } // 终止捕获 if (currentLine.Equals("Shipping Address", StringComparison.OrdinalIgnoreCase)) { isCapturing = false; break; // 找到结束标记后直接退出循环,减少不必要遍历 } // 处于捕获状态时收集行 if (isCapturing) { billingLines.Add(lines[i]); } }
这种方式仅遍历集合一次,时间复杂度为O(n),适合需要在遍历过程中执行额外逻辑的场景。
Linq高效实现
Linq可以让代码更简洁,同时保持O(n)的时间复杂度,非常适合快速实现需求:
针对IList集合(如List)
利用FindIndex快速定位标记位置,再通过Skip和Take提取中间内容:
// 定位起始标记索引 int startIndex = lines.FindIndex(line => line.Trim().Equals("Billing Address", StringComparison.OrdinalIgnoreCase)); // 从起始索引后开始定位结束标记 int endIndex = lines.FindIndex(startIndex + 1, line => line.Trim().Equals("Shipping Address", StringComparison.OrdinalIgnoreCase)); List<string> billingLines = new List<string>(); // 确保索引有效且顺序正确 if (startIndex != -1 && endIndex != -1 && endIndex > startIndex) { billingLines = lines.Skip(startIndex + 1).Take(endIndex - startIndex - 1).ToList(); }
针对IEnumerable集合
如果你的集合是无法直接通过索引访问的IEnumerable<T>,可以先将元素与索引绑定后再处理:
var indexedLines = lines.Select((line, index) => new { Line = line, Index = index }).ToList(); // 找到起始和结束标记 var startMarker = indexedLines.FirstOrDefault(x => x.Line.Trim().Equals("Billing Address", StringComparison.OrdinalIgnoreCase)); var endMarker = indexedLines.FirstOrDefault(x => startMarker != null && x.Index > startMarker.Index && x.Line.Trim().Equals("Shipping Address", StringComparison.OrdinalIgnoreCase)); List<string> billingLines = new List<string>(); if (startMarker != null && endMarker != null) { billingLines = indexedLines.Where(x => x.Index > startMarker.Index && x.Index < endMarker.Index) .Select(x => x.Line) .ToList(); }
关键注意点
- 匹配规则:使用
StringComparison.OrdinalIgnoreCase可忽略大小写匹配,若需要严格区分大小写,替换为StringComparison.Ordinal即可。 - 多标记处理:如果集合中存在多个相同标记,可根据业务需求将
FindIndex替换为LastIndexOf,或FirstOrDefault替换为LastOrDefault来选择目标标记。 - 性能对比:两种方式效率相近,Linq胜在代码简洁易读,传统循环更适合需要精细控制遍历流程的场景。
内容的提问来源于stack exchange,提问作者JaisG
相关产品推荐
相关产品推荐

