Nodejs - 转换数组

时间:2015-09-15 22:15:34

标签: javascript arrays node.js

我有一个表格中的数组:

[
{id:'4704',sub_elements:['123456','7890123','5566778']},
{id:'4706',sub_elements:['223344','7890123','1111111']},
....
]

该数组大约有2500个元素,每个子数组也有数百个元素。

我希望使用交换的元素转换此数组。即。

[
'123456': ['4704'],
'7890123': ['4704','4706'],
'5566778': ['4704'],
'223344' : ['4706'],
'1111111' : ['4706']
]

一种方法是从第一个数组中取出所有子元素并将它们推送到数组中。然后重新删除数组。

所以你最终得到的结果是:

var sub_elements = ['123456','7890123','5566778', '223344','7890123','1111111', ....] //50,000+ elements

然后迭代那个(非常庞大的列表)。伪代码:

var original = [
{id:'4704',sub_elements:['123456','7890123','5566778']},
{id:'4706',sub_elements:['223344','7890123','1111111']},
....
]; //2,000+ elements
var elements = ['123456','7890123','5566778', '223344','7890123','1111111'];

var result = {};

for(element in elements){
    var ids = [];
    for(var x in original){
        if(original[x].sub_elements.indexOf(elements[element]) >= 0){
            ids.push(original[x].id);
        }
    }
    result[elements[element]] = ids;
}

问题在于,在去除数组中有如此多的元素,这在Node中占用绝对年龄。必须有一种更有效的方法来做到这一点。实际上,元素的大小是50K +元素。所以它迭代所有50K元素,并且对于每次迭代,它迭代原始数组。

目前树林里的树木 - 也许这里有人已经做过这样的事了。

3 个答案:

答案 0 :(得分:1)

假设你真正想要的是一个从“子元素”值映射到原始的“id”值的对象,你可以立刻做到这一点我认为:

var transformed = original.reduce(function(rv, entry) {
  entry.sub_elements.forEach(function(subelem) {
    if (rv[subelem])
      rv[subelem].push(entry.id);
    else
      rv[subelem] = [entry.id];
  });
  return rv;
}, {});

这将为您提供一个对象,其中属性名称是子元素值的集合,并且每个属性的值是id的数组(可能具有重复项),其中子元素值出现在原始值中。

代码通过使用.reduce()遍历原始数组来工作,从一个新的空对象开始。对于每个原始数组条目,然后迭代“子元素”列表,以在每个子元素条目的键下的整体结果中构建“id”值列表。

编辑 - 如果结果真的很重要,那么结果应该是一个真实的数组实例,而不是一个对象(它不会像似乎那样会产生影响,因为不清楚为什么你会关心.length在这种情况下会告诉你什么),你可以使用与相同的代码来做到这一点

var transformed = original.reduce(function(rv, entry) {
  // same same
}, []); // <--- [] instead of {} to initialize the process

答案 1 :(得分:1)

默认情况下,节点js只在一个线程中运行,因此请求的所有队列(池请求)应该是异步的,但是解析数组(超过50K)的代码是同步代码,并将阻止所有传入的请求(或者池中的请求),你将失去很多性能。 要解析像这样的大数组,你应该使用node js ticket函数,如下所示:

var result = {};
var original = [{'id': 1, subElements: [1,2,3]}, {...}, {...}, ...];

var processBigArray = function() {
    // 
    if(original.length !== 0) {
        process.nextTick(function processItemFromArray() {
           var item = original.shift();
           // perform the operations
           // .... doing operations ....

           // if there are more elements, process on next tick
           if(original.length !== 0) {
               process.nextTick();
           }
        });
    }

};

processBigArray();

如果节点中有一些传入请求(或池中的其他事件),则使用process.nextTick,然后节点将处理下一个传入事件,然后处理数组的下一个项目,这样,传入事件将永远不会被阻止。

答案 2 :(得分:0)

更新: 不要在真实数组上使用for ... in。值以任意顺序

for ... in