获取两个数组/字符串之间的差异(添加和删除)

时间:2014-10-06 00:17:10

标签: javascript arrays algorithm comparison difference

我有一个array,它会被用户输入(键盘)更新。我想跟踪哪些条目发生变化以获得更好的现场表现。

这是一个例子:

// ascii values for 'Stuckoverflow'
var previousBlocks = [
     83, 116, 117, 99, 107, 111, 118,
     101, 114, 102, 108, 111, 119
];

// ascii values for 'Stackedoverflow2014'
var blocks = [
     83, 116, 97, 99, 107, 101, 100, 111, 118,
     101, 114, 102, 108, 111, 119,
     50, 48, 49, 52
];

我想获取已从previousBlocks添加或删除到blocks的条目的位置。较大的未更改部分应保持不变。 (在这种情况下'溢出')

var result = {
    deletions: [2],
    additions: [2, 5, 6, 13, 14, 15, 16]
};

人类可读,差异可以这样表达:

St[-u][+a]ck[+e][+d]overflow[+2][+0][+1][+4]

1 个答案:

答案 0 :(得分:0)

由于array被用户操纵(通过键入),因此会对更改进行聚类。此解决方案计算一个更改范围并确定替换块。这是一个非常简单的解决方案,但它可以完成它的工作。

var start = 0;
var end = 0;
var length = Math.min(previousBlocks.length, length);

// compare from left to right
while (
    start < length
    && previousBlocks[start]
        == blocks[start]
) {
    start ++;
}

// compare from right to left
while (
    end < length - start
    && previousBlocks[previousBlocks.length - end - 1]
        === blocks[blocks.length - end - 1]
) {
    end ++;
}

// collect the blocks that have been added
var rangeBlocks = [];
for (var i = start; i < blocks.length - end; i ++)
{
    rangeBlocks.push(blocks[i]);
}

return {
    // unchanged amount of blocks on the left
    startOffset: start,

    // unchanged amount of blocks on the right
    endOffset: end,

    // exchange / replace the changed part by these blocks
    blocks: rangeBlocks
};