Javascript 两个阵列的智能合并(3路)

Javascript 两个阵列的智能合并(3路),javascript,merge,Javascript,Merge,我有两个数组,每个数组代表一个故事列表。两个用户可以同时修改顺序、添加或删除故事,我希望合并这些更改 举个例子可以让这一点更清楚 Original 1,2,3,4,5 UserA (mine) 3,1,2,4,5 (moved story 3 to start) UserB (theirs) 1,2,3,5,4 (moved story 5 forward) 上述结果应为: Merge (result) 3,1,2,5,4 如果发生冲突,UserA应该始终获胜 我用这种简单的

我有两个数组,每个数组代表一个故事列表。两个用户可以同时修改顺序、添加或删除故事,我希望合并这些更改

举个例子可以让这一点更清楚

Original       1,2,3,4,5
UserA (mine)   3,1,2,4,5 (moved story 3 to start)
UserB (theirs) 1,2,3,5,4 (moved story 5 forward)
上述结果应为:

Merge (result) 3,1,2,5,4
如果发生冲突,UserA应该始终获胜

我用这种简单的方法取得了很大的进步。首先,我删除了我说我应该删除的任何内容(代码的这部分没有显示,这很琐碎),然后我在我的代码上迭代,插入并移动他们需要的内容(mstories=我的,tstories=他们的):


for(var idx=0;idx这里有一个函数,它迭代提供的数组,并让另一个函数决定如何在给定索引处合并。(请参阅)

…以及在冲突时引发异常的:

function complain( original, a, b ) {
    if (original == a )
        return b;

    if (original == b )
        return a;

    if ( a == b )
        return a;

    throw ("conflict");
}

// throws "conflict at index 3"    
merge(
    [1,2,3,4,5],
    [3,1,2,1,5],
    [1,2,3,5,4], complain);

签出通常用于协作系统中并发控制的操作转换。Google Wave大量使用它来保持文档同步。Wikipedia-有趣的问题!我非常希望看到它的解决方案。我尝试了一段时间,但没有成功,也许我会在不头疼的时候再试一次。OT确实帮助了我。解决方案是提取两个更改的操作集(移动、插入、删除),然后将其中一个更改(基本上是偏移量)转换为在另一个更改之后适用。然后应用这两个。我现在怀疑,在我尝试的一个循环中是否可以理解这一点。
// params:
//   original, a, b: equally dimensioned arrays
//   mergeStrategy : function with params _original, _a, _b that
//                   accept the values inhabiting the arrays
//                   original, a, and b resp.
//       
//                  - Is called for each array index.  
//                  - Should return one of the arguments passed.
//                  - May throw "conflict" exception.
// returns merged array

function merge(original, a, b, mergeStrategy){
    var result=[];

    for ( var i =0; i< a.length; i++ )  {
        try {
            result.push( mergeStrategy( original[i], a[i], b[i] ));
        } catch (e if e=="conflict") {
            throw ("conflict at index "+i);
        }
    }
    return result;
}
// example:  always choose a over b
function aWins( original, a, b ) {
    return ( original == a ) ? b : a;
}

// returns [3,1,2,5,4]    
merge(
    [1,2,3,4,5],
    [3,1,2,4,5],
    [1,2,3,5,4], aWins);
function complain( original, a, b ) {
    if (original == a )
        return b;

    if (original == b )
        return a;

    if ( a == b )
        return a;

    throw ("conflict");
}

// throws "conflict at index 3"    
merge(
    [1,2,3,4,5],
    [3,1,2,1,5],
    [1,2,3,5,4], complain);