// 2017/01/20
if (typeof window == 'undefined') {
// node.js
module.exports = $Map_;
}
/**
* 類似(Map)的功能
*/
function $Map_(dataList) {
var self = this;
this.fn = this.constructor;
this.size = 0;
// this.keys = []; // [key, key.......]
this.dataList = []; // [{k: key, v: value}, {k: key, v: value}.....]
function __constructor() {
if (Array.isArray(dataList)) {
self.dataList = dataList;
self.size = self.dataList.length;
}
};
__constructor();
};
////////////////////////////////////////////////////////////////////////////////
(function() {
/**
*
* @return {Map}
*/
this.set = function(key, value) {
var index;
var data = {
'k': key,
'v': value
};
if ((index = this.indexOfKey(key)) >= 0) {
// 若(key)已經存在
this.dataList[index] = data;
} else {
this.dataList.push(data);
this.size = this.dataList.length;
}
return this;
};
/* ====================================================================== */
this.get = function(key) {
var index, index, _k, valueObj, checkCount = 0;
if ((index = this.indexOfKey(key)) <= 0) {
// 若沒找到(key)
return undefined;
}
/* ---------------------------------- */
var data = this.dataList[index];
return data.v;
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
(function() {
/* ====================================================================== */
this.clear = function() {
this.dataList = [];
this.size = this.dataList.length;
};
/* ====================================================================== */
this.delete = function(key) {
var index, result = false;
if ((index = this.indexOfKey) >= 0) {
this.dataList.splice(index, 1);
this.size = this.dataList.length;
result = true;
}
return result;
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
(function() {
this.indexOfKey = function(key) {
var index = -1;
if (key == null) {
return index;
}
this.dataList.some(function(data, i) {
var _key = data.k || undefined;
if (_key === key) {
index = i;
return true;
}
});
return index;
};
/* ====================================================================== */
this.has = function(key) {
var index, result = false;
if ((index = this.indexOfKey(key)) >= 0) {
result = true;
}
return result;
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
(function() {
/**
* 主要的不同處,返回(array)
*
* @return {array} [keys]
*/
this.keys = function() {
var keys_array = [];
this.dataList.forEach(function(data) {
var key = data.k;
keys_array.push(key);
});
return keys_array;
};
/* ====================================================================== */
/**
* 主要的不同處,返回(array)
*
* @return {array} [values]
*/
this.values = function() {
var values_array = [];
this.dataList.forEach(function(data) {
var values = data.v;
values_array.push(values);
});
return values_array;
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
(function() {
this.entries = function() {
var result = [];
this.dataList.forEach(function(obj) {
result.push([obj.k, obj.v]);
});
return this.fn.makeIterator(result);
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
(function() {
this.forEach = function(callback, _this) {
var self = this;
_this = _this || this;
this.dataList.forEach(function(data, i) {
var k = data.k;
var v = data.v;
/* ------------------------ */
var copyKey = k;
var copyData = self.__clone(v);
/* ------------------------ */
callback.call(_this, copyData, copyKey, self);
});
};
/* ====================================================================== */
this.some = function(callback, _this) {
var self = this;
_this = _this || this;
var result = false;
this.dataList.some(function(data, i) {
var k = data.k;
var v = data.v;
var copyKey = k;
var copyData = self.__clone(v);
/* ------------------------ */
result = callback.call(_this, copyData, copyKey, self);
if (result !== true) {
result = false;
}
/* ------------------------ */
return result;
});
return result;
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
(function() {
this.map = function() {
};
/* ====================================================================== */
this.filter = function() {
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
(function() {
/**
* 依照(key)排序
*/
this.keySort = function(sortFun) {
if (typeof sortFun != 'function') {
throw new TypeError('sortFun must be function');
}
this.dataList.sort(_sortFun);
/* ---------------------------------- */
function _sortFun(a, b) {
// 排序的函式
var key_a = a.k || undefined;
var key_b = b.k || undefined;
return sortFun(key_a, key_b);
}
};
/* ====================================================================== */
this.valueSort = function(sortFun) {
if (typeof sortFun != 'function') {
throw new TypeError('sortFun must be function');
}
this.dataList.sort(_sortFun);
/* ---------------------------------- */
function _sortFun(a, b) {
// 排序的函式
var value_a = a.v || undefined;
var value_b = b.v || undefined;
var result = sortFun(value_a, value_b);
return result;
}
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
(function() {
/**
* 複製
*/
this.slice = function() {
'use strict';
// debugger;
var arg = [].slice.call(arguments);
var copyDataList = this.dataList.slice.apply(this.dataList, arg);
var map = new $Map_(copyDataList);
return map;
};
/* ====================================================================== */
/**
* 移除,拼接(不能新增)
*/
this.splice = function(start, count) {
'use strict';
// debugger;
var copyDataList;
if (arguments.length == 0) {
copyDataList = this.dataList.splice();
} else if (arguments.length == 1) {
copyDataList = this.dataList.splice(start);
} else {
// arguments.length > 1
copyDataList = this.dataList.splice(start, count);
}
var map = new $Map_(copyDataList);
/* ---------------------------------- */
this.size = this.dataList.length;
return map;
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
(function() {
this.__clone = function(data) {
return this.fn.readDataOnly(data);
};
this.toJSON = function() {
var result = [];
this.dataList.forEach(function(obj) {
result.push([obj.k, obj.v]);
});
return result;
};
}).call($Map_.prototype);
////////////////////////////////////////////////////////////////////////////////
//
// ($Map_)類別方法
//
// $Map_.readDataOnly(data)
//
// $Map_.makeIterator(array);
//
////////////////////////////////////////////////////////////////////////////////
(function(self) {
var toString = Object.prototype.toString;
/**
* 能複製([]{}Map)三中資料格式
* ([]{})的表層只能讀取
*/
self.readDataOnly = function(source) {
var toString = Object.prototype.toString;
var clone;
var type = _getType(source);
if (/array/gi.test(type) || _isPlainObject(source)) {
// source is [], {}
clone = _copyProperty(source);
} else if (/map/gi.test(type)) {
// source is Map
clone = _copyMap(source);
} else {
clone = source;
}
return clone;
};
/* ====================================================================== */
/**
* copy([], {})
*/
function _copyProperty(source) {
debugger;
if (!isObject(source)) {
return source;
} else {
var copy;
var prototype = Object.getPrototypeOf(source);
/* ---------------------------------- */
if (typeof prototype != 'undefined') {
copy = Object.create(prototype);
} else {
copy = Object.create(null);
}
/* ---------------------------------- */
copyProperty(copy, source);
return copy;
}
/* =========================================== */
/**
* 是否是Object
*/
function isObject(value) {
debugger;
var result = (value === Object(value));
return result;
};
/* =========================================== */
function copyProperty(copy, source) {
var propertys = Object.getOwnPropertyNames(source);
console.dir(propertys);
propertys.forEach(function(property) {
var desc = Object.getOwnPropertyDescriptor(source, property);
// 禁止表層資料被修改新增刪除
desc.writable = false;
desc.configurable = false;
Object.defineProperty(copy, property, desc);
});
};
};
/* ====================================================================== */
/**
* copy map
*/
function _copyMap(source) {
var cloneMap = new Map();
source.forEach(function(v, k) {
cloneMap.set(k, v);
});
return cloneMap;
};
/* ====================================================================== */
/**
* 確定型別
*/
function _getType(obj) {
var type = toString.call(obj) || '';
type = type.replace(/(^\s?\[object\s?)|(\]\s?$)/gi, '').toLowerCase();
return type;
};
/* ====================================================================== */
/**
* 是否是{}
*/
function _isPlainObject(obj) {
if (!obj || _getType(obj) !== "object") {
return false;
}
var constructorName = '';
try {
constructorName = obj.constructor.toString();
} catch (error) {}
// 'Object() {[native code]}'
if (!/function\s*Object\(\s*\)\s*\{\s*\[native\s*code\]\s*\}\s*$/gi.test(constructorName)) {
return false;
}
return true;
};
})($Map_);
////////////////////////////////////////////////////////////////////////////////
(function(self) {
/* ====================================================================== */
self.makeIterator = function(array) {
if (!Array.isArray(array)) {
throw new Error('makeIterator must be array');
}
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ? {
value: array[nextIndex++],
done: false
} : {
done: true
};
}
}
};
})($Map_);