使用Power Query或TypeScript实现重复值替换而非删除行
重复值替换为"cont."(保留整行)的实现方案
需求说明:某列存在大量重复值,不删除重复值所在整行,仅将首次出现后的重复值替换为字符串"cont."。
原始数据
| 行号 | 日期 |
|---|---|
| 1 | 01.01.2023 |
| 2 | 01.01.2023 |
| 3 | 01.01.2023 |
| 4 | 02.01.2023 |
| 5 | 01.01.2023 |
| 6 | 03.01.2023 |
| 7 | 02.01.2023 |
期望结果
| 行号 | 日期 |
|---|---|
| 1 | 01.01.2023 |
| 2 | cont. |
| 3 | cont. |
| 4 | 02.01.2023 |
| 5 | cont. |
| 6 | 03.01.2023 |
| 7 | cont. |
Power Query 实现步骤
可视化操作流程
- 将数据导入Power Query编辑器
- 添加索引列(从0开始,用于标记行顺序)
- 按「日期」列分组,设置分组操作为最小索引(记录每个日期首次出现的位置)
- 将原表与分组后的表按「日期」列左连接
- 添加条件列:如果当前行索引等于该日期的最小索引,保留原日期;否则填入"cont."
- 移除多余的辅助列,重命名条件列为「日期」
直接可用的M代码
let 源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content], // 替换"表1"为你的实际表名 添加索引 = Table.AddIndexColumn(源, "索引", 0, 1, Int64.Type), 分组获取首次索引 = Table.Group(添加索引, {"日期"}, {{"首次出现索引", each List.Min([索引]), Int64.Type}}), 合并表格 = Table.NestedJoin(添加索引, {"日期"}, 分组获取首次索引, {"日期"}, "分组数据", JoinKind.LeftOuter), 展开分组列 = Table.ExpandTableColumn(合并表格, "分组数据", {"首次出现索引"}, {"首次出现索引"}), 生成新日期列 = Table.AddColumn(展开分组列, "新日期", each if [索引] = [首次出现索引] then [日期] else "cont."), 清理冗余列 = Table.RemoveColumns(生成新日期列,{"索引", "日期", "首次出现索引"}), 重命名列 = Table.RenameColumns(清理冗余列,{{"新日期", "日期"}}) in 重命名列
TypeScript 实现方案
核心思路
先清理日期中的HTML标签(如果有),然后用Map记录每个日期首次出现的位置,遍历数据时判断是否为首次出现,非首次则替换为"cont."。
完整代码示例
// 带HTML标签的原始数据 const rawDataWithHtml = [ { rowNumber: 1, date: "<em>01.01.2023</em>" }, { rowNumber: 2, date: "<strong>01.01.2023</strong>" }, { rowNumber: 3, date: "<strong>01.01.2023</strong>" }, { rowNumber: 4, date: "<em>02.01.2023</em>" }, { rowNumber: 5, date: "<strong>01.01.2023</strong>" }, { rowNumber: 6, date: "<em>03.01.2023</em>" }, { rowNumber: 7, date: "<strong>02.01.2023</strong>" }, ]; // 去除HTML标签的工具函数 const stripHtmlTags = (htmlStr: string): string => { const tempElement = document.createElement('div'); tempElement.innerHTML = htmlStr; return tempElement.textContent?.trim() || tempElement.innerText?.trim() || ''; }; // 清理数据中的HTML标签 const cleanedData = rawDataWithHtml.map(item => ({ ...item, date: stripHtmlTags(item.date) })); // 处理重复值 const firstOccurrenceMap = new Map<string, number>(); const finalData = cleanedData.map(item => { if (!firstOccurrenceMap.has(item.date)) { firstOccurrenceMap.set(item.date, item.rowNumber); return item; } return { ...item, date: "cont." }; }); // 输出结果 console.log(finalData);
纯数据场景(无HTML标签)
如果原始数据已经是干净的日期字符串,直接跳过HTML清理步骤即可。
内容的提问来源于stack exchange,提问作者maliebina
相关产品推荐
相关产品推荐

