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

如何将fast-diff生成的diff数组转换为基于原字符串位置的精简格式

优化fast-diff结果存储:用原字符串位置替换重复文本

问题场景

我有一个会随机变化的大字符串,需要跟踪其变更并重建最终内容。目前使用fast-diff库生成diff数组,但当原字符串很大(比如10000字符)而变更很少时,diff数组里类型为0(未更改)的条目会存储大量重复文本,造成冗余。

原diff格式示例

原字符串:Hello everyone, my name is Chris
变更后字符串:Hello everyone, my fame is gone
fast-diff生成的原diff数组:

[
  [ 0, 'Hello everyone, my ' ],
  [ -1, 'n' ],
  [ 1, 'f' ],
  [ 0, 'ame is ' ],
  [ -1, 'Chris' ],
  [ 1, 'gone' ]
]

目标优化格式

希望把类型0的条目替换为原字符串的起止位置引用,减少存储成本,优化后的diff数组:

[
    [0, { start: 0, end: 19 }],
    [-1, 'n'],
    [1, 'f'],
    [0, { start: 20, end: 27 }],
    [-1, 'Chris'],
    [1, 'gone']
]

实现函数

核心逻辑是按顺序跟踪原字符串的当前偏移位置,避免直接搜索子串导致的重复匹配问题。函数遍历原diff数组,根据条目类型更新偏移量并转换格式:

function convertDiffToPositionRefs(originalText, diffArray) {
    const convertedDiff = [];
    let currentOffset = 0;

    for (const [type, content] of diffArray) {
        if (type === 0) {
            // 未更改内容:计算起止位置
            const start = currentOffset;
            const end = currentOffset + content.length;
            convertedDiff.push([0, { start, end }]);
            // 更新偏移量:原字符串中这段内容已处理完
            currentOffset = end;
        } else if (type === -1) {
            // 删除内容:直接保留,偏移量加上删除的长度
            convertedDiff.push([-1, content]);
            currentOffset += content.length;
        } else if (type === 1) {
            // 新增内容:直接保留,偏移量不变(新增内容不在原字符串里)
            convertedDiff.push([1, content]);
        }
    }

    return convertedDiff;
}

测试示例

const originalText = 'Hello everyone, my name is Chris';
const originalDiff = [
  [ 0, 'Hello everyone, my ' ],
  [ -1, 'n' ],
  [ 1, 'f' ],
  [ 0, 'ame is ' ],
  [ -1, 'Chris' ],
  [ 1, 'gone' ]
];

const optimizedDiff = convertDiffToPositionRefs(originalText, originalDiff);
console.log(optimizedDiff);
// 输出与目标格式一致

验证重建功能

从优化后的diff数组和原字符串重建最终字符串:

function reconstructFinalText(originalText, optimizedDiff) {
    let finalText = '';
    for (const [type, data] of optimizedDiff) {
        if (type === 0) {
            // 从原字符串截取对应位置的内容
            finalText += originalText.slice(data.start, data.end);
        } else if (type === 1) {
            // 新增内容直接追加
            finalText += data;
        }
        // 删除内容忽略,因为重建最终字符串不需要
    }
    return finalText;
}

console.log(reconstructFinalText(originalText, optimizedDiff));
// 输出:Hello everyone, my fame is gone

内容的提问来源于stack exchange,提问作者codemonkey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 14:47:32