我有一个表格中的数组:
[
{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元素,并且对于每次迭代,它迭代原始数组。
目前树林里的树木 - 也许这里有人已经做过这样的事了。
答案 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
。值以任意顺序