合并对象的两个数组最有效的方法 [英] Most efficient way to merge two arrays of objects

查看:164
本文介绍了合并对象的两个数组最有效的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经解决了这一点。但是我在寻找,因为我的变量更快的解决方案有成千上万个对象。

I've already solved this out. However I'm looking for a faster solution since my variables has thousands of objects.

我有两个数组是这样的:

I have two arrays like this:

var full = [{a:'aa1',b:'bb1'},{a:'aa3',b:'bb2'},{a:'aa3',b:'bb3'},{a:'aa2',b:'bb3'}],
some = [{a:'aa1',b:'bb1'},{a:'aa3',b:'bb3'}]; 

我想为标记 C 称为一个新的属性在完全如果在对象上存在一些。预期结果:

I'm trying to flag in a new attribute called c in full if the object exist on some. Expected result:

 [{a:'aa1',b:'bb1',c:true},{a:'aa3',b:'bb2'},{a:'aa3',b:'bb3',c:true},{a:'aa2',b:'bb3'}]

一些重要的提示:

Some important tips:

  • 在一些总是比全
  • 更少的元件
  • 在两个数组排序等于

我目前的做法是:

var getIndexByAB = function(arr, a,b){
     var initialIndex =  getIndexByAB.initialIndex || 0,
     len = arr.length;
     for(initialIndex; initialIndex < len ;initialIndex++ ){
         var el = arr[initialIndex];
         if( el.b === b && el.a === a ){
             getIndexByAB.initialIndex = initialIndex;
             return initialIndex;
         }
     }
     return -1;
}

var len = some.length;
for(var i = 0; i < len ; i++){
 var el=some[i],
 index = getIndexByAB(full,el.a,el.b);
 if(index > -1) full[index].c = true;
}

UPDADE :使用胡安评论原液改善。

UPDADE: original solution improved using Juan comment.

推荐答案

由于它们的排序,你可以通过索引从开始搜索,这将避免为O(n ^ 2)。你已经这样做,但通​​过存储在索引中的全局变量。相反,你应该把它作为参数传递给 getIndexByAB

Since they are sorted, you can just pass an index to start the search from, that will avoid the O(n^2). You were already doing it, but by storing the index in a global variable. Instead, you should pass it as an argument to getIndexByAB.

function getIndexByAB(arr, a,b , initialIndex){
    // Was tracking last index by storing it in a global 'this.initialIndex'. 
    // 'this' points to 'window' in global functions. That's bad, it 
    // means this function can't be called on different arrays without
    // resetting the global 

    // var initialIndex =  this.initialIndex || 0,

    initialIndex = initialIndex || 0;
    var len = arr.length;
    for(initialIndex; initialIndex < len ; initialIndex++ ){
        var el = arr[initialIndex];
        if( el.b === b && el.a === a ){
            // Bad globals
            // this.initialIndex = initialIndex;
            return initialIndex;
        }
    }
    return -1;
}

var len = some.length;
var lastValidIndex = 0;
for(var i = 0; i < len ; i++){
    var el = some[i];
    // Pass the index here, so it doesn't start from scratch
    var index = getIndexByAB(full, el.a, el.b, lastValidIndex);
    if(index > -1) {
        full[index].c = true;
        lastValidIndex = index;
    }
}

顺便说一句,如果你想一个函数来缓存一些价值观,这里是如何做到这一点,避免全局。 (不是说你应该使用它在这种情况下)

By the way, if you do want a function to cache some values, here's how to do it avoiding globals. (Not that you should use it in this case)

var getIndexByAB = (function(){
     // This will only be executed once, and is private
     // to getIndexByAB (all invocations)
     var lastGoodIndex = 0;

     return function(arr, a,b, resetIndex){
         if (resetIndex) {
            lastGoodIndex = 0;
         }

         var len = arr.length;
         for(var index = lastGoodIndex; index < len ; index++ ){
             var el = arr[index];
             if( el.b === b && el.a === a ){                 
                 lastGoodIndex = index;
                 return index;
             }
         }
         return -1;
    };
})();

另外,你可以实现在 getIndexByAB.initialIndex 缓存它下面的,但它不是很优雅。主要理由要避开这是一个事实,即 getIndexByAB.initialIndex 可以通过别人修改

Alternatively, you could achieve the following by caching it in getIndexByAB.initialIndex but it's not very elegant. The main reason for avoiding this is the fact that getIndexByAB.initialIndex can be modified by anybody else

这篇关于合并对象的两个数组最有效的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆