recherche

Maison  >  Questions et réponses  >  le corps du texte

javascript中,对于元素是对象的数组,用underscore取不到交集?why

js 数组:

var a = [{name:'huge',age:23},{name:'lee',age:24}];
var b = [{name:'huge',age:23},{name:'lee',age:24}];

两个一模一样的数组,用underscore的取交集函数,结果为[]。
为什么呢?

阿神阿神2897 Il y a quelques jours396

répondre à tous(3)je répondrai

  • 伊谢尔伦

    伊谢尔伦2017-04-10 15:02:05

    underscore取交集是取引用的交集吧

    var a = {name:'huge',age:23};
    var b = {name:'huge',age:23};

    注意
    a !== b;

    因为引用的不是同一块地址噢

    répondre
    0
  • 迷茫

    迷茫2017-04-10 15:02:05

    这个不是underscore的问题,是你对javascript的数据类型的理解不够。
    对象是属于引用类型,不是值类型,所以两个对象相等,通常是指他们指向同一个位置。

    javascriptvar aa = {
        name: 'aa',
        age: '89'
    }
    // 上面是创建了一个对象,并返回这个对象的引用(类似于C语言的指针),它其实是个类似于物理地址的东西。
    
    var bb = {
        name: 'aa',
        age: '89'
    }
    // 这个bb虽然看起来和aa的一样,但是创建这个对象的时候,它是使用的另一块存储空间,即返回的引用是不一样的
    
    console.log(aa === bb); // false
    

    répondre
    0
  • 阿神

    阿神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);
    

    可以根据需要自行删减代码。

    répondre
    0
  • Annulerrépondre