Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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_Mapreduce - Fatal编程技术网

JavaScript-“;结合;两个相似的对象数组

JavaScript-“;结合;两个相似的对象数组,javascript,arrays,node.js,mapreduce,Javascript,Arrays,Node.js,Mapreduce,假设我有以下两个数组: let arr1 = [ { id: "1234567890", name: "Someone", other: "unneeded", props: 123 } ... ]; let arr2 = [ { id: "1234567890", points: 100, other: "unneeded", props: 456 } ... ]; 我需要根据名称和按id的点组合这些,如下所示: [ { id: "1234567890", name: "Someone",

假设我有以下两个数组:

let arr1 = [ { id: "1234567890", name: "Someone", other: "unneeded", props: 123 } ... ];
let arr2 = [ { id: "1234567890", points: 100, other: "unneeded", props: 456 } ... ];
我需要根据名称和按id的点组合这些,如下所示:

[ { id: "1234567890", name: "Someone", points: 100 } ... ]
一种选择是这样映射它们:

let final = arr1.map(u => ({
    id: u.id,
    name: u.name,
    points: arr2.find(uu => uu.id === u.id)
}));
但是,对于较大的数组(数千个条目),这是低效的,因为
find()
每次都会迭代数组。我正在努力提高效率。我读了一遍,但这似乎不是答案(除非我错了)。如何执行此操作?

您可以从第二个数组的对象创建一个数组,以便可以在固定时间内通过id直接访问相应的对象:

让arr1=[
{id:1234567890,姓名:“某人”,其他:“不需要的”,道具:123},
{id:1234567891,姓名:“Someone1”,其他:“多余的1”,道具:124},
{id:1234567892,姓名:“Someone2”,其他:“不需要的2”,道具:125}
];
设arr2=[
{id:1234567890,点数:100,其他:“不需要”,道具:456},
{id:1234567891,点数:101,其他:“不需要”,道具:457},
{id:1234567892,点数:102,其他:“不需要”,道具:458}
];
让arr2Map=arr2.reduce((a,c)=>{
a、 集合(c.id,c);
返回a;
},新地图());
让final=arr1.map({id,name,points})=>
({id,name,points:arr2Map.get(id.points | | points}));

控制台日志(最终)您可以尝试的一种解决方案是。如果您以前没有使用过它们,它们可以在单独的线程中运行脚本,本质上允许您使用多个内核来处理某些内容。它们非常适合于并行任务,这意味着任务可以在没有任何中断的情况下分解。它们将非常适合您的用例,因为您只是在数据上绘制一幅大地图

但在走这条路之前,您应该提前得到警告,webworkers会有一些开销。为了将数据放入webworker,必须将其序列化到线程中,然后在返回时对其进行反序列化。然而,如果你把你的任务分成不同的工作,并让它们并行运行,你应该能够缓解其中的一些问题

// app.js
let largeArray = []; // contains the large amount of arrays to map
let outputArray = []; 
while(largeArray.length){
    let worker = new Worker('/path/to/worker/script.js');
    worker.postMessage({
        chunk: largeArray.splice(0,1000)
    });
    worker.onmessage = evt => {
        let data = evt.data;
        outputArray = outputArray.concat(data);
        worker.terminate();
    }
}
另外还有一个辅助脚本,可能类似于此脚本,可供参考

// workerScript.js
self.onmessage = ({data: {chunk}}) => {
    let final = chunk.map(u => ({
        id: u.id,
        name: u.name,
        points: arr2.find(uu => uu.id === u.id)
    }));
    self.postMessage(final);
}
你可能会问关于序列化的问题,它是自动发生的。Webworkers有自己的全局作用域,通过序列化,您可以发送对象、数组和原语。所有这些都可以序列化。但是,具有自定义属性和类的对象将抛出错误。在幕后,它基本上是获取您的数据并执行
JSON.stringify({{your data}})
,然后在webworker中,数据成为
JSON.parse({{serialized data}})
的结果


因为这项工作是在不同的线程中进行的,所以在运行应用程序的主线程上不会看到任何阻塞。但是,如果您试图一次处理太多的数据,序列化会很明显,因为它会一直阻塞到完成。

您在这里使用的组合逻辑是什么?@Ashish如最后一个数组的示例所示,我想“合并”由
id
编辑的
name
points
的id是否始终是一个整数?@TommiTuura编辑过,本应是一个字符串,但是的,它始终是一个字符串