合并对象的两个数组最有效的方法数组、最有效、对象、两个

2023-09-11 06:37:05 作者:开水养活鱼i

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

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