这是我参与更文挑战的第1天,活动详情查看: 更文挑战
准备. 此工具是对数组元素的操作, 因此先准备针对元素操作的工具.
/**
* js compare
* <p><i>注意: deepCompare({0:'a', length:1, __proto__:Array(0)}, ['a']) 在Chrome中也会返回true.</i></p>
* @example
* console.assert(deepCompare({0:'a'}, {0:'a'}), '粗大事儿了!');
*
* @return {boolean}
*/
function deepCompare() {
var args = arguments, l = args.length;
if (l < 2) {
return true;
// throw "Need two or more arguments to compare";
}
var arg0 = args[0];
var i, leftChain, rightChain;
var compare2Objects = function (x, y) {
var p;
// remember that NaN === NaN returns false
// and isNaN(undefined) returns true
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
return true;
}
// Compare primitives and functions.
// Check if both arguments link to the same object.
// Especially useful on the step where we compare prototypes
if (x === y) {
return true;
}
// Works in case when functions are created in constructor.
// Comparing dates is a common scenario. Another built-ins?
// We can even handle functions passed across iframes
if ((typeof x === 'function' && typeof y === 'function') ||
(x instanceof Date && y instanceof Date) ||
(x instanceof RegExp && y instanceof RegExp) ||
(x instanceof String && y instanceof String) ||
(x instanceof Number && y instanceof Number)) {
return x.toString() === y.toString();
}
// At last checking prototypes as good as we can
if (!(x instanceof Object && y instanceof Object)) {
return false;
}
if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
return false;
}
if (x.constructor !== y.constructor) {
return false;
}
if (x.prototype !== y.prototype) {
return false;
}
// Check for infinitive linking loops
if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
return false;
}
// Quick checking of one object being a subset of another.
for (p in y) {
if (y.hasOwnProperty(p) ^ x.hasOwnProperty(p)) {
return false;
} else if (typeof y[p] !== typeof x[p]) {
return false;
}
}
for (p in x) {
if (y.hasOwnProperty(p) ^ x.hasOwnProperty(p)) {
return false;
} else if (typeof y[p] !== typeof x[p]) {
return false;
}
switch (typeof(x[p])) {
case 'object':
case 'function':
leftChain.push(x);
rightChain.push(y);
if (!compare2Objects(x[p], y[p])) {
return false;
}
leftChain.pop();
rightChain.pop();
break;
default:
if (x[p] !== y[p]) {
return false;
}
break;
}
}
return true;
}
for (i = 1; i < l; i++) {
// clear before each compare as it can be cached
leftChain = [];
rightChain = [];
if (!compare2Objects(arg0, args[i])) {
return false;
}
}
return true;
}
/**
* 内容比较器
* @type {deepCompare}
*/
Array.comparable = deepCompare
/**
* 元素在集合中的索引
* @param {*} a 元素
* @param {function} [comparable] 比较器. 默认用 <code>===</code> 来比较.
* @return {number}
*/
Array.prototype.at = function(a, comparable){
comparable = comparable || Array.comparable
if(!comparable) {
return this.indexOf(a);
}
for(var i = 0; i < this.length; i++){
if(comparable(a, this[i])){
return i;
}
}
return -1;
}
/**
* 集合中是否包含元素
* @param {*} a 元素
* @return {boolean}
*/
Array.prototype.contains = function(a){
return this.at(a) > -1;
}
/**
* 元素唯一
* @example
* [1,3,2,3].unique() // returns [1,3,2]
* @return {[]} 不重复元素的集合
*/
Array.prototype.unique = function(){
return this.reduce(function (c, v) {
if (!c.contains(v)){
c.push(v);
}
return c;
}, []);
}
/**
* 全集
* @example
* [[1],[2],[3]].unionAll([[2],[4],[6]]) // returns [[1], [2], [3], [2], [4], [6]]
* @return {*[]}
*/
Array.prototype.unionAll = function() {
return Array.prototype.concat.apply(this, arguments);
}
/**
* 并集
* @example
* [[1],[2],[3]].union([[2],[4],[6]]) // returns [[1], [2], [3], [4], [6]]
* @return {*[]}
*/
Array.prototype.union = function () {
return Array.prototype.unionAll.apply(this, arguments).unique();
}
/**
* 差集
* @example
* [[1],[2],[3]].minus([[2],[4],[6]]) // returns [[1], [3]]
* [[2],[4],[6]].minus([[1],[2],[3]]) // returns [[4], [6]]
* @param {Array} a 要剔除的元素集合
* @return {*[]}
*/
Array.prototype.minus = function (a) {
return this.reduce(function (c, v) {
if (!a.contains(v)){
c.push(v);
}
return c;
}, []);
}
/**
* 补集
* @example
* [[1],[2],[3]].complement([[2],[4],[6]]) // returns [[1], [3], [4], [6]]
* @param {Array} a
* @return {*[]}
*/
Array.prototype.complement = function (a) {
return this.minus(a).concat(a.minus(this));
}
/**
* 交集
* @example
* [[1],[2],[3]].intersect([[2],[4],[6]]) // returns [[2]
* @param {Array} a
* @return {*[]}
*/
Array.prototype.intersect = function (a) {
return this.reduce(function (c, v) {
if (a.contains(v)){
c.push(v);
}
return c;
}, []);
}
/**
* 数组求和
* @example
* // returns 11
* [2,4,5].sum()
* // returns 266
* var arr = [
* {yu: 113, shu: 123, wai: 115, wu: 75, hua: 90, sheng: 100},
* {yu: 123, shu: 143, wai: 123, wu: 90, hua: 100, sheng: 100}
* ]
* arr.sum(it=>it.shu)
* // returns 740
* arr.sum(it=>it.yu + it.shu + it.wai)
* // returns {yu: 236, shu: 266, wai:238}
* arr.sum(['yu','shu','wai'])
* @param {function|Array} [field] 求和条件
* @returns {number|Object}
*/
Array.prototype.sum = function(field){
var a = this;
return typeof field==='function'?Array.prototype.reduce.call(a,function(c,v){
return c += field(v);
},0)
:Array.isArray(field)?Array.prototype.reduce.call(field,function(c, v){
c[v] = (c[v]||0) + Array.prototype.sum.call(a, function(it){
return it[v];
});
return c;
},{})
:!field?Array.prototype.reduce.call(a,function(c,v){
return c += v;
},0):0;
}
/**
* 分组
* @example
* var arr = [
* {code: "001", language: "2", content: "3"},
* {code: "001", language: "2", content: "4"},
* {code: "001", language: "3", content: "5"},
* {code: "001", language: "3", content: "6"},
* {code: "002", language: "1", content: "3"},
* {code: "002", language: "2", content: "3"},
* {code: "001", language: "2", content: "4"}
* ]
* arr.groupBy(it=>it.code)
* arr.groupBy('code')
* @param {string|function} group 分组字符段(一个)
* @return {Object} 以分组字段为key的Object
*/
Array.prototype.groupBy = function(group){
return group && typeof group==='function'?Array.prototype.reduce.call(this, function(c, v){
var k = group(v);
c[k] = (c[k]||[]).concat(v);
return c;
},{}):group && typeof group==='string' && group.length?this.reduce(function(c, v){
var k = v[group];
c[k] = (c[k]||[]).concat(v);
return c;
},{}):this;
}
感觉注释都写的差不多了.
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!