Maison > Questions et réponses > le corps du texte
js 数组:
var a = [{name:'huge',age:23},{name:'lee',age:24}]; var b = [{name:'huge',age:23},{name:'lee',age:24}];
两个一模一样的数组,用underscore的取交集函数,结果为[]。
为什么呢?
伊谢尔伦2017-04-10 15:02:05
underscore取交集是取引用的交集吧
var a = {name:'huge',age:23};
var b = {name:'huge',age:23};
注意
a !== b;
因为引用的不是同一块地址噢
迷茫2017-04-10 15:02:05
这个不是underscore的问题,是你对javascript的数据类型的理解不够。
对象是属于引用类型,不是值类型,所以两个对象相等,通常是指他们指向同一个位置。
javascript
var aa = { name: 'aa', age: '89' } // 上面是创建了一个对象,并返回这个对象的引用(类似于C语言的指针),它其实是个类似于物理地址的东西。 var bb = { name: 'aa', age: '89' } // 这个bb虽然看起来和aa的一样,但是创建这个对象的时候,它是使用的另一块存储空间,即返回的引用是不一样的 console.log(aa === bb); // false
阿神2017-04-10 15:02:05
_.intersection = function (array) {
if (array == null) return [];
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = array.length; i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};
_.contains = _.include = function (obj, target) {
if (obj == null) return false;
if (obj.length !== +obj.length) obj = _.values(obj);
return _.indexOf(obj, target) >= 0;
};
问题就出在这个contains上,包含比较的是引用,不是单纯的值。
_.contains([{name:'xxx'}],{name:'xxx'});//false
var s={name:'xxx'};
_.contains([s],s);//true
_.intersection求交集不是深比较,所以只能传递基本类型的数据,不能传递对象作为参数哦!
拉个angularjs的equals代码给你瞅瞅,比较两个对象是否相等。深比较,里面还有递归,代码很长,因为它所有的情况都考虑到了。
有了这个方法就可以实现取对象的交集了。
function isDate(value) {
return Object.prototype.toString.call(value) === '[object Date]';
}
function isRegExp(value) {
return Object.prototype.toString.call(value) === '[object RegExp]';
}
function isFunction(value) {
return typeof value === 'function';
}
function equals(o1, o2) {
if (o1 === o2) return true;
if (o1 === null || o2 === null) return false;
var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
if (t1 == t2) {
if (t1 == 'object') {
if (Array.isArray(o1)) {
if (!Array.isArray(o2)) return false;
if ((length = o1.length) == o2.length) {
for (key = 0; key < length; key++) {
if (!equals(o1[key], o2[key])) return false;
}
return true;
}
} else if (isDate(o1)) {
if (!isDate(o2)) return false;
return equals(o1.getTime(), o2.getTime());
} else if (isRegExp(o1) && isRegExp(o2)) {
return o1.toString() == o2.toString();
} else {
//if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || Array.isArray(o2)) return false;
keySet = {};
for (key in o1) {
if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
if (!equals(o1[key], o2[key])) return false;
keySet[key] = true;
}
for (key in o2) {
if (!keySet.hasOwnProperty(key) &&
key.charAt(0) !== '$' &&
o2[key] !== undefined && !isFunction(o2[key])) return false;
}
return true;
}
}
}
return false;
}
function intersection(array) {
var result = [];
var argsLength = arguments.length;
for (var i = 0; i < argsLength; i++) {
var item = array[i];
if (contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
}
function contains(obj, target) {
if (obj == null) return false;
var flag = false;
for (var i = 0; i < obj.length; i++) {
if (equals(obj[i], target)) {
flag = true;
}
}
return flag;
}
var a = [{name: 'huge', age: 23}, {name: 'lee', age: 24}];
var b = [{name: 'huge', age: 23}, {name: 'd', age: 24}];
var c = intersection(a, b);
console.log(c);
可以根据需要自行删减代码。