Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript和集合_Javascript_Arrays_Node.js_Performance_Indexing - Fatal编程技术网

Javascript和集合

Javascript和集合,javascript,arrays,node.js,performance,indexing,Javascript,Arrays,Node.js,Performance,Indexing,在javascript/NodeJs中有3个列表/数组 数组包含1.000.000个数据项 数组包含100.000个数据项 数组包含50000个数据项 每个数据项都是一个具有两个属性的对象,如日期和价格。 数组2和3中的所有项都是数组1中项的子集/子列表 我的问题:对于数组1中的每个项目,如何以最快的方式将数组1中每个项目的所有日期与数组2和数组3中的所有日期进行匹配 我已经习惯了.NET/C#-其中类似“contains(item)”的内容很好。。。现在在NodeJS中,我使用3作为循环-这是

在javascript/NodeJs中有3个列表/数组

  • 数组包含1.000.000个数据项
  • 数组包含100.000个数据项
  • 数组包含50000个数据项
  • 每个数据项都是一个具有两个属性的对象,如日期和价格。 数组2和3中的所有项都是数组1中项的子集/子列表

    我的问题:对于数组1中的每个项目,如何以最快的方式将数组1中每个项目的所有日期与数组2和数组3中的所有日期进行匹配

    我已经习惯了.NET/C#-其中类似“contains(item)”的内容很好。。。现在在NodeJS中,我使用3作为循环-这是一种减慢速度的方法…我需要某种索引或类似的东西来加速这个过程

    数据示例如下所示:

    输入:

    array 1: 1,2,3,4,5,6,7,8,10
    array 2: 2,3,5,7,9
    array 3: 1,4,5,10
    
    输出(写入文件):


    我会尝试首先按键属性(Date,afaiu)对所有数组进行排序(如果尚未排序),然后在第一个数组上使用一个for循环,并在另外两个数组中使用游标,这将仅在当前项写入输出时移动到下一项。这样就不会在整个数组中进行任何“包含”搜索

    例如:

    var j = 0;
    var k = 0;
    for( var i = 0; i < array1.length; ++i ) {
        var out1 = array1[i].date;
        var out2 = j < array2.length && array2[j].date == out1 ? array2[j++].value : '';
        var out3 = k < array3.length && array3[k].date == out1 ? array3[k++].value : '';
        output( out1, out2, out3 );
    }
    
    var j=0;
    var k=0;
    对于(变量i=0;i
    这将是一个线性操作,首先对数据进行排序的折衷可能值得,也可能不值得花时间进行排序

    这与三重连接差不多,我提供的解决方案是O(N),其中嵌套循环可能是O(N^3),排序的解决方案可能仍然是O(Nlog(N)),只是一个猜测

    如果已经对日期进行了排序,则可以对日期进行bucketize或进行某种基数搜索,这样可能会加快排序速度

    见:

    您还可以使用Promissions来执行此操作,因此它可以异步运行:

    var t = {}
    // loop through once and create a constant time lookup
    arr1.forEach(function(item){t[item.date] = {1: item.price, 2: null, 3:null})
    
    var promiseArray = arr2.map(function(item){
        return Promise.resolve(item)
            .then(function(item){
                  if (t[item.date]) t[item.date].2 = item.price})
             })
    // concat the two promise arrays together 
    promiseArray.concat(arr3.map(function(item){
        return Promise.resolve(item)
            .then(function(item){
                  if (t[item.date]) t[item.date].3 = item.price})
             }))
    // resolve all the promises
    Promise.all(promiseArray)
        .then(function(){
            // t has results
            debugger
        })
    

    这是javascript!考虑将数组重构为对象,以便Dead属性将成为一个键,例如: var arr2={'2016-05-13 00:00:01':{prop:'value',prop2:'value'},'2016-05-13 00:00:02':{prop:'value',prop2:'value'},…};
    这样,arr2[date]要么返回对象,要么返回未定义的对象。如果你得到一个对象,把它转换成适合输出的字符串;否则写“”或其他任何东西。

    如果数组被排序,我想JS中最快的数组求交算法是这样的

    function intersect(a1, a2)
    {
      var a1i = 0,
          a2i = 0,
        isect = [];
    
      while( a1i < a1.length && a2i < a2.length ){
        if (a1[a1i].date < a2[a2i].date) a1i++;
         else if (a1[a1i].date > a2[a2i].date) a2i++;
         else {isect.push(a1i); // they match
               a1i++;
               a2i++;}
      }
    
      return isect;
    }
    

    “”;
    是否有重复的日期?日期是一个
    日期对象还是一个字符串?能否包含一个示例对象,其日期和价格可能匹配,也可能不匹配?您使用了多少RAM?在my postgresql db中,日期保存为“带时区的时间戳”。“2014-12-01 05:33:56.761199+00数据项示例:新交易点(日期、价格)-如果日期匹配,则将价格添加到新列表/行中。。。关于记忆,尽可能少。。。2-4-8gb…每个列表中没有重复的日期/项。@PabloDK,数组是否保证提前排序?使用数组而不是对象是否有原因?让我重新表述我的问题:不要使用具有2个属性的小对象,而是将其推到数组中。是否有其他结构/类型的集合在javascript中更快/性能更好(特别是在尽可能快地在数组中查找给定对象方面)?这正是我目前正在做的。。。但我认为javascript中一定有一种更快的方法?是的-所有列表/数组按日期按相同顺序排序…@PabloDK,请检查我刚才添加的示例。你确定你在做那样的事吗?因为您编写了3个for循环,而可以只使用一个。您必须将长度存储在变量中。@Knu,OMG,这只是一个带有2个附加游标的单个for循环的概念,我在手机上键入了它。当然,任何在循环内被反复解析为常量的值,都必须在循环外只计算一次。但是这个优化对问题的作者来说太明显了,所以我决定不让这个例子过于复杂。@JustAndrei-我看到了你的代码循环并遍历了array1…但是我看到的方式是代码-它没有遍历array2或array3?它只需要进行一次比较(var out2=j集群
    模块完成的,它需要消息传递。它的好处在于,当处理大量传入请求时,请求或多或少会在每个核心之间实现负载平衡。通过使用承诺编写它,它为单个线程/核心/事件循环提供了在不阻塞的情况下处理其他传入请求的机会。因此,在承诺等待解决的同时,如果有其他请求进来,好处就会显现出来。关于共享内存的答案,请参阅:我认为那里的评论建议
    ems
    ,但可能更容易将
    var t
    卸载到redis实例中,并使用分叉承诺访问它。另一种想法是,这对node既有好处也有坏处。我不记得所有的细节…但一旦我
    var t = {}
    // loop through once and create a constant time lookup
    arr1.forEach(function(item){t[item.date] = {1: item.price, 2: null, 3:null})
    
    var promiseArray = arr2.map(function(item){
        return Promise.resolve(item)
            .then(function(item){
                  if (t[item.date]) t[item.date].2 = item.price})
             })
    // concat the two promise arrays together 
    promiseArray.concat(arr3.map(function(item){
        return Promise.resolve(item)
            .then(function(item){
                  if (t[item.date]) t[item.date].3 = item.price})
             }))
    // resolve all the promises
    Promise.all(promiseArray)
        .then(function(){
            // t has results
            debugger
        })
    
    function intersect(a1, a2)
    {
      var a1i = 0,
          a2i = 0,
        isect = [];
    
      while( a1i < a1.length && a2i < a2.length ){
        if (a1[a1i].date < a2[a2i].date) a1i++;
         else if (a1[a1i].date > a2[a2i].date) a2i++;
         else {isect.push(a1i); // they match
               a1i++;
               a2i++;}
      }
    
      return isect;
    }