努力在数组中存储字符位置

问题描述 投票:0回答:1

对于模棱两可的标题感到非常抱歉,因为我根本不知道如何用一行描述我的问题。

我有一个以随机间隔不断变化的字符串。我希望能够跟踪该字符串的更改,然后能够重建最终的字符串。

示例:

const text1 = 'Hello everyone, my name is Chris';
//12 seconds later it turns into:
const text2 = 'Hello everyone, my fame is gone';
//... Keeps changing...

我正在使用这个名为 fast-diff 的优秀库来比较字符串并存储 diff 数组。这是它的工作原理:

const text1 = 'Hello everyone, my name is Chris';
const text2 = 'Hello everyone, my fame is gone';
const diff_array = diff(text1, text2, 1);
console.log(diff_array);

结果是:

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

其中 0 表示未更改的字符,1 表示添加的字符,-1 表示删除的字符。

基于这个 diff 数组,我可以通过运行如下命令轻松重建

'Hello everyone, my fame is gone'

diff_array.forEach(el => {
    if(el[0] !== -1)
        process.stdout.write(el[1]);
})

我要做的就是将数组存储在某个地方。

问题:在处理大字符串时,当前构建的 diff 数组会存储大量冗余,因为大多数时候对 10,000 个字符串的更改是最小的。

目标:我想做的是存储原始字符串并从

转换差异数组
[
  [ 0, 'Hello everyone, my ' ],
  [ -1, 'n' ],
  [ 1, 'f' ],
  [ 0, 'ame is ' ],
  [ -1, 'Chris' ],
  [ 1, 'gone' ]
]

至:

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

]

其中 0 代替 参考未更改的原始文本的开始和结束字符位置。这将大大降低我的存储成本。我需要一个函数来接受原始文本和 diff 数组,并吐出一个与上面类似的新 diff 数组。

我在这里苦苦挣扎的原因是因为在原始字符串中搜索

'Hello everyone, my '
'ame is '
并找到它们的位置并不是一个简单的问题,因为这些子字符串也可以在其他地方。我必须按顺序搜索它,同时跟踪当前搜索位置在哪里。

javascript diff
1个回答
0
投票

从 fast-diff 返回的差异有额外的信息,您不需要从原始数据中重建,可能会出于验证目的而保留。因此,您可以做的就是将它们删除,基本上对于删除和复制操作,只需存储一个数字,而这只是您需要保留字符串的添加操作。

例如。您展示的示例 diff 可以直接制作为 ->

[[0,19],[-1,1],[1,"f"],[0,7],[-1,5],[1,"gone"]]

下面是使用此技术的工作片段。

function makeShortDifs(d) {
  return d.map(m => {
    let [action, value] = m;
    if (action !== 1) value = value.length;
    return [action, value];
  });
}

function makeNew(o, difs) {
  let n = '', p = 0;
  for (const d of difs) {
    const [action, value] = d;
    if (action === 0) {
      n += o.slice(p, p + value);
      p += value;
    } else if (action === 1) {
      n += value;
    } else p += value;
  }
  return n;
}


///Test...

//difs we get from fast-diff
const bigDifs = [
  [ 0, 'Hello everyone, my ' ],
  [ -1, 'n' ],
  [ 1, 'f' ],
  [ 0, 'ame is ' ],
  [ -1, 'Chris' ],
  [ 1, 'gone' ]
];

//make our diffs smalll
const smallDifs = makeShortDifs(bigDifs);

//now test small diffs on original text.
const original = 'Hello everyone, my name is Chris';
console.log(original);
console.log(makeNew(original, smallDifs));

© www.soinside.com 2019 - 2024. All rights reserved.