123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- function defaultKeyGetter(item) {
- return item;
- }
- function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter, context) {
- this._old = oldArr;
- this._new = newArr;
- this._oldKeyGetter = oldKeyGetter || defaultKeyGetter;
- this._newKeyGetter = newKeyGetter || defaultKeyGetter;
- this.context = context;
- }
- DataDiffer.prototype = {
- constructor: DataDiffer,
- /**
- * Callback function when add a data
- */
- add: function (func) {
- this._add = func;
- return this;
- },
-
- update: function (func) {
- this._update = func;
- return this;
- },
-
- remove: function (func) {
- this._remove = func;
- return this;
- },
- execute: function () {
- var oldArr = this._old;
- var newArr = this._new;
- var oldDataIndexMap = {};
- var newDataIndexMap = {};
- var oldDataKeyArr = [];
- var newDataKeyArr = [];
- var i;
- initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, '_oldKeyGetter', this);
- initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter', this);
- for (i = 0; i < oldArr.length; i++) {
- var key = oldDataKeyArr[i];
- var idx = newDataIndexMap[key];
- if (idx != null) {
-
-
- var len = idx.length;
- if (len) {
- len === 1 && (newDataIndexMap[key] = null);
- idx = idx.shift();
- } else {
- newDataIndexMap[key] = null;
- }
- this._update && this._update(idx, i);
- } else {
- this._remove && this._remove(i);
- }
- }
- for (var i = 0; i < newDataKeyArr.length; i++) {
- var key = newDataKeyArr[i];
- if (newDataIndexMap.hasOwnProperty(key)) {
- var idx = newDataIndexMap[key];
- if (idx == null) {
- continue;
- }
- if (!idx.length) {
- this._add && this._add(idx);
- } else {
- for (var j = 0, len = idx.length; j < len; j++) {
- this._add && this._add(idx[j]);
- }
- }
- }
- }
- }
- };
- function initIndexMap(arr, map, keyArr, keyGetterName, dataDiffer) {
- for (var i = 0; i < arr.length; i++) {
-
- var key = '_ec_' + dataDiffer[keyGetterName](arr[i], i);
- var existence = map[key];
- if (existence == null) {
- keyArr.push(key);
- map[key] = i;
- } else {
- if (!existence.length) {
- map[key] = existence = [existence];
- }
- existence.push(i);
- }
- }
- }
- var _default = DataDiffer;
- module.exports = _default;
|