首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >两个数组的智能合并(3-way-kindof)

两个数组的智能合并(3-way-kindof)
EN

Stack Overflow用户
提问于 2010-04-26 16:02:23
回答 1查看 511关注 0票数 4

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

举个例子应该会让这一点更清楚。

代码语言:javascript
复制
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)

上面的结果应该是

代码语言:javascript
复制
Merge (result) 3,1,2,5,4

在发生冲突的情况下,UserA应该始终获胜。

我用这个简单的方法走了很远。首先,我删除了我认为应该删除的任何内容(这部分代码没有显示,很琐碎),然后我迭代我的代码,插入和移动他们的所需内容(mstories =我的,tstories =他们的):

代码语言:javascript
复制
     for (var idx=0;idx<mstories.length;idx++) {
        var storyId = mstories[idx];

        // new story by theirs
        if (tstories[idx] !== undefined && mstories.indexOf(tstories[idx]) == -1) {
           mstories.splice(idx+1, 0, tstories[idx]);
           idx--;
           continue;
        }
        // new story by mine
        if (tstories.indexOf(storyId) == -1 && ostories.indexOf(storyId) == -1) {
           tstories.splice(idx+offset, 0, storyId);
           offset += 1;
        // story moved by me
        } else if ((tstories.indexOf(storyId) != idx + offset) && ostories.indexOf(storyId) != idx) {
           tstories.splice(tstories.indexOf(storyId), 1);
           tstories.splice(idx+offset, 0, storyId);
        // story moved by them
        } else if (tstories.indexOf(storyId) != idx + offset) {
           mstories.splice(mstories.indexOf(storyId), 1);
           mstories.splice(idx+offset, 0, storyId);
           mdebug(storyId, 'S moved by them, moffset--');
        }
     }
     result = tstories

它很接近,但是当太多的故事被移到前面/后面,中间有故事,另一个用户触摸时,它就会变得混乱。

我有一个扩展版本,它可以对原始版本进行检查,而且更智能-持有2个偏移量,等等-但我觉得这是一个问题,必须有一个名字b)一个完美的解决方案,我不想重新发明它。

EN

回答 1

Stack Overflow用户

发布于 2010-05-21 21:06:16

下面是一个函数,它迭代所提供的数组,并让另一个函数决定如何在给定的索引处合并。(参见Strategy Pattern)

代码语言:javascript
复制
// 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;
}

下面是一些用法示例。你的:

代码语言:javascript
复制
// 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);

..。和一个在冲突时抛出异常的方法:

代码语言:javascript
复制
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);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2711879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档