如何用LINQ获取重复元素索引及后续空元素范围(Excel合并单元格场景)
问题描述
复制Excel中的垂直合并单元格会得到如下ComplexArray数组:
Dim ComplexArray As String() = Split("A C A B C A B A B C")
需要实现两个需求:
- 获取列中重复元素的数量、重复元素的行差值并按重复元素降序排列
- 使用LINQ获取重复元素的索引及其后续空元素的范围,得到类似
Need_result的结果:
Dim Need_result= {({"A", ({"0-2", "5-9", "16-16", "19-20"})}), ({"B", ({"10-12", "17-18", "21-24"})}), ({"C", ({"3-4", "13-15", "25-25"})})}
解决方案
1. 统计重复元素信息并降序排列
通过LINQ分组统计元素出现次数,计算相邻出现的行差值,最后按出现次数降序排列:
' 过滤非空元素并保留索引 Dim indexedElements = ComplexArray.Select(Function(s, i) New With {.Value = s, .Index = i}) .Where(Function(x) Not String.IsNullOrEmpty(x.Value)) ' 分组统计核心逻辑 Dim elementStats = indexedElements.GroupBy(Function(x) x.Value) .Select(Function(g) New With { .Element = g.Key, .Count = g.Count(), .RowDifferences = g.Select(Function(x, idx) If(idx > 0, x.Index - g.ElementAt(idx-1).Index, Nothing)) .Where(Function(d) d IsNot Nothing) .ToList() }) .OrderByDescending(Function(x) x.Count) ' 输出统计结果 For Each stat In elementStats Console.WriteLine($"元素: {stat.Element}, 数量: {stat.Count}") Console.WriteLine($"行差值: {String.Join(", ", stat.RowDifferences)}") Console.WriteLine() Next
2. 获取重复元素索引及后续空元素范围
遍历非空元素,定位每个元素后续连续空元素的结束索引,生成目标范围结构:
' 计算每个元素的索引范围 Dim result = indexedElements.Select(Function(x) Dim nextNonEmptyIndex = indexedElements.FirstOrDefault(Function(y) y.Index > x.Index)?.Index Dim endIndex = If(nextNonEmptyIndex IsNot Nothing, nextNonEmptyIndex - 1, ComplexArray.Length - 1) Return New With { .Element = x.Value, .Range = $"{x.Index}-{endIndex}" } End Function) .GroupBy(Function(x) x.Element) .Select(Function(g) New With { .Element = g.Key, .Ranges = g.Select(Function(r) r.Range).ToArray() }) .OrderByDescending(Function(x) x.Ranges.Length) .ToArray() ' 转换为与Need_result一致的数组结构 Dim needResultLike = result.Select(Function(r) {r.Element, r.Ranges}).ToArray() ' 输出范围结果 For Each item In needResultLike Console.WriteLine($"元素: {item(0)}") Console.WriteLine($"范围: {String.Join(", ", item(1))}") Console.WriteLine() Next
逻辑说明
- 先过滤数组中的空元素并保留原始索引,为后续统计和范围计算打基础
- 统计环节通过分组获取元素出现次数,同时计算相邻出现位置的差值
- 范围计算时,通过当前元素的下一个非空元素位置确定覆盖终点;若为最后一个元素,则覆盖到数组末尾
- 最终按元素出现次数降序排列,生成符合要求的结果结构
内容的提问来源于stack exchange,提问作者Mansour Dalir
相关产品推荐
相关产品推荐

