【发布时间】:2011-02-12 07:16:31
【问题描述】:
我有两个数组,每个数组代表一个故事列表。两个用户可以同时修改订单、添加或删除故事,我希望将这些更改合并。
一个例子应该更清楚
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 = mine,tstories = theirs):
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 个偏移量等 - 但我觉得这是一个必须有 a) 名称 b) 完美解决方案的问题,而我没有想要重新发明它。
【问题讨论】:
-
Checkout 操作转换,通常用于协作系统中的并发控制。 Google Wave 大量使用它来保持文档同步。 waveprotocol.org/whitepapers/operational-transform,维基百科 - en.wikipedia.org/wiki/Operational_transformation
-
有趣的问题!我非常希望看到它的解决方案。我试了一会儿没有运气,也许我不头疼的时候再试一次。
-
确实 OT 帮助了我。解决方案是为两个更改提取一组操作(移动、插入、删除),然后将其中一个更改(基本上是偏移量)转换为在另一个更改之后适用..然后同时应用两者。我现在怀疑这是否可以在我尝试的一个循环中被理解。
标签: javascript merge