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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 09:16:12