2015-10-05 42 views
2

我以包含嵌套对象(〜34,000项)的大数组开始,并且每5秒轮询一次,接收数组的更新(通常为2-3一次更新),新阵列只包含已更改的项目(例如,如果只有3个项目发生更改,我只能获得更新阵列中的这3个项目。)JavaScript中的快速方式用新值更新现有阵列

我尝试了下列使用下划线,但它需要9秒,我需要一秒钟或更少。

getUniqueUnion(new, old) { 
    return uniq(union(new, old), false, function(item) { 
     return item.info.id; 
    }); 
    } 

任何人都有一个快速方法的建议吗?如果有帮助,唯一的关键是info.id,而我真正想要检测的唯一更改(原因是我需要更新该项目)是否inStock值发生变化。换句话说,如果inStock值没有改变,我不需要对该数组项进行任何更新。

实例阵列:

const originalData = [ 
    { 
    info: { 
     id: 1 
    }, 
    moreInfo: { 
     name: 'hamburger', 
     inStock: true 
    } 
    }, 
    ... // 33,999 more 
] 



const updatedData = [ 
    { 
    info: { 
     id: 1 
    }, 
    moreInfo: { 
     name: 'hamburger', 
     inStock: false 
    } 
    }, 
    ... // maybe 2 more 
] 

所以最终的阵列将包括有moreInfo.inStock ===第一项虚假

+2

如果您知道需要更新的条目的id,应该查找“id”,然后更新*只有该条目*而不是重新写入整个阵列 –

+0

是id的顺序?他们从1开始到34000,还是更随机? –

+0

我想我太过于复杂了,我可以在for循环中使用for循环并更改该条目,而不是重写,谢谢@HunterMcMillen。 – Ben

回答

1

阅读您的情况后,这里是我的建议:

  1. 排序的大阵。你只需要一次,所以不用担心。在排序的数组中查找值总是比未排序的数组更快更容易。
  2. 循环使用您的updatedData,取一个项目,在您的排序数组中寻找它(originalData),使用二进制搜索。根据需要更新它。

要了解如何在JavaScript中实现二进制搜索,您可以参考此post或此one

0

我肯定是过于复杂这一点。这是我提出的解决方案,但如果有人知道更快的事情,我会很感激。

function updateArray(latest, current) { 
    for (let i = 0, len = current.length; i < len; i++) {  
    for (let g = 0, len = latest.length; g < len; g++) { 
     if (latest[g].module.id === current[i].module.id) { 
     current[i] = latest[g]; 
     break; 
     } 
    } 
    } 

    return current; 
} 
+0

如果'latest'和'current'的长度是相似的,那么这个速度仍然很慢'O(n^2)'(假设n接近于m。你可以使用二分搜索来查找你需要在'O(log n)'时间而不是'O(n)'中更新的元素 –

+0

因为info.id是唯一的,所以为什么不用一个散列?要做的是通过最新的数组,并简单地覆盖当前散列中的匹配条目。 – subdigit

+0

'latest'将会非常小,比如1-3个元素 – Ben