有時候我們需要區分一堆 List 的 changeset。特別是當這個 List 可以被增加可以被修改可以被刪除的時候。
需要獲得以下幾個 List
added_list
updated_list
deleted_list
unchanged_list
寫了一個 JS 實現。
入參是四個 original
, current
, getKeyFunction
, checkUpdatedFunction
前兩個沒什麼好說了。
getKeyFunction
預設是返回入參本身。如果入參 List 是 Object 可以返回這個 Object 的 Oid 之類的值。checkUpdatedFunction
是比對是否有修改過的方法。預設比對兩個 Object 的 JSON 值。
磚頭還是輕輕的來比較好 ……
function getChangeSet(original, current, getKeyFunction, checkUpdatedFunction) {
original = [].concat(original);
current = [].concat(current);
if (getKeyFunction == undefined) {
getKeyFunction = function(item) {
return item;
}
}
if (checkUpdatedFunction == undefined) {
checkUpdatedFunction = function(obj1, obj2) {
return JSON.stringify(obj1) != JSON.stringify(obj2);
}
}
var listToMap = function(list) {
var ret = {};
for (var i = 0, l = list.length; i < l; i++) {
ret[getKeyFunction(list[i])] = list[i];
}
return ret;
};
var getValueListOfMap = function(map) {
var ret = [];
for (var key in map) {
if (map.hasOwnProperty(key)) {
ret.push(map[key]);
}
}
return ret;
};
var getKeyListOfMap = function(map) {
var ret = [];
for (var key in map) {
if (map.hasOwnProperty(key)) {
ret.push(key);
}
}
return ret;
};
var weightMap = {},
calWeight = function(list, weight, weightMap) {
for (var i = 0, l = list.length; i < l; i++) {
var key = list[i];
if (typeof weightMap[key] === "number") {
weightMap[key] += weight;
} else {
weightMap[key] = weight;
}
}
}
var added = [],
updated = [],
deleted = [],
unchanged = [];
var oriMap = listToMap(original),
curMap = listToMap(current),
oriKeys = getKeyListOfMap(oriMap),
curKeys = getKeyListOfMap(curMap);
calWeight(oriKeys, 1, weightMap);
calWeight(curKeys, 2, weightMap);
for (var key in weightMap) {
if (weightMap.hasOwnProperty(key)) {
var value = weightMap[key];
if (value == 3) {
if (checkUpdatedFunction(oriMap[key], curMap[key])) {
updated.push(curMap[key]);
} else {
unchanged.push(oriMap[key]);
}
} else if (value == 2) {
added.push(curMap[key]);
} else if (value == 1) {
deleted.push(oriMap[key]);
}
}
}
return {
added: added,
updated: updated,
deleted: deleted,
unchanged: unchanged
};
}
以下 tests 通過了
test1 = function() {
var ori = ['t1', 't2'];
var cur = ['t1', 't3'];
return getChangeSet(ori, cur)
}
test2 = function() {
var ori = [{
key: 't1',
value: 'v1'
}, {
key: 't2',
value: 'v2'
}, {
key: 't4',
value: 'v4'
}];
var cur = [{
key: 't1',
value: 'vx'
}, {
key: 't3',
value: 'v3'
}, {
key: 't4',
value: 'v4'
}];
return getChangeSet(ori, cur,
function(item) {
return item.key;
})
}