Javascript 确定对象集合是否已更改的最有效方法是什么?

Javascript 确定对象集合是否已更改的最有效方法是什么?,javascript,Javascript,我以前从后端获取过一个集合。我正在轮询后端以进行更改,并已收到另一个集合。数据集大小合理,因此我们不需要任何优化。。。只是把整件事又拿回来了 通过算法f(previousCollection,newCollection)运行这两个数据集,我想为添加的、删除的和修改的生成结果 最有效的方法是什么?或者,更确切地说,你们在日常工作中是如何做到这一点的 示例数据: 旧的: 新的: 预期结果: {event: 'removed', id: 1}, {event: 'modified', id: 2},

我以前从后端获取过一个集合。我正在轮询后端以进行更改,并已收到另一个集合。数据集大小合理,因此我们不需要任何优化。。。只是把整件事又拿回来了

通过算法
f(previousCollection,newCollection)
运行这两个数据集,我想为添加的
删除的
和修改的
生成结果

最有效的方法是什么?或者,更确切地说,你们在日常工作中是如何做到这一点的

示例数据:

旧的:

新的:

预期结果:

{event: 'removed', id: 1},
{event: 'modified', id: 2},
{event: 'added', id: 4}
使用Array#reduce和Array#find使这变得非常简单

函数f(上一个,当前){
var结果=上一个减少(函数(结果,p){
变量c=当前查找(函数(项){
return item.id==p.id;
});
如果(c){
如果(c.foo!==p.foo){
push({event:'modified',id:p.id});
}
}否则{
push({event:'removed',id:p.id});
}
返回结果;
}, []);
返回电流减少(函数(结果,c){
var p=上一个查找(功能(项目){
return item.id==c.id;
});
如果(!p){
push({event:'added',id:c.id});
}
返回结果;
},结果);
}
var old=[
{id:1,foo:'bar'},
{id:2,foo:'bar'}
];
var curr=[
{id:2,foo:'qux'},
{id:4,foo:'bar'}
];

控制台日志(f(旧,当前))这是一个更全面的比较

可能的变化:
  • 更新属性的值
  • 添加了一个新属性
  • 删除了一个属性。这可能与值不同时更改的值重叠
  • 删除一个对象
  • 将添加一个新对象
/*
地位:
关键是,
删除密钥,
添加的对象,
对象已删除,
被改进的,
有重复的
*/
函数getUpdates(旧的、新的状态){
var结果=[];
//创建新副本
old=old.slice(0);
newState=newState.slice(0);
//删除的对象
不匹配的hingObject(旧、新状态、结果)
old.forEach(函数(o){
var报告={};
report.id=o.id;
var match=newState.filter(函数(项){
return item.id==o.id
});
var mlen=match.length;
if(mlen){
if(mlen==1&&stringMatch(o,match[0])返回
如果(mlen>1)report.hasdeplicate=true;
match.forEach(函数(m,索引){
if(stringMatch(o,m))返回
关键字匹配(o、m、索引、报告)
匹配值(o、m、索引、报告)
})
}
if(Object.keys(report.length>1)
结果推送(报告)
});
返回结果
}
函数字符串匹配(o1,o2){
返回JSON.stringify(o1)==JSON.stringify(o2);
}
功能键匹配(o1、o2、索引、报告){
var k1=对象键(o1);
var k2=对象键(o2);
如果(k1.join()!==k2.join()){
report.keysRemoved=(report.keysRemoved | | |[])
var r=k1.过滤器(函数(k){
返回k2.indexOf(k)<0;
});
report.keysRemoved.push({
钥匙:r,
objectIndex:索引
});
report.keysAdded=(report.keysAdded | |[]))
变量a=k2.过滤器(功能(k){
返回k1.indexOf(k)<0;
});
report.keysAdded.push({
钥匙:a,
objectIndex:索引
})
}
}
函数匹配值(o1、o2、索引、报告){
report.keysChanged=report.keysChanged | |[];
var键=[];
用于(o1中的var k){
如果(o1[k]!==o2[k]&&o2[k]){
按键。按(k);
}
}
report.keysChanged.push({
钥匙:钥匙,
objectIndex:索引
})
}
函数不匹配hingObject(o1、o2、结果){
var ids1=o1.map(函数(o){
返回o.id
});
var ids2=o2.map(函数(o){
返回o.id
});
ids1.forEach(函数(id){
if(ids2.indexOf(id)<0)
结果:推({
id:id,
状态:“对象已删除”
})
})
ids2.forEach(函数(id){
if(ids1.indexOf(id)<0)
结果:推({
id:id,
状态:“已添加对象”
})
})
}
var old=[{
id:1,
福:“酒吧”
}, {
id:2,
福:“酒吧”
}, {
id:3,
傅:“测试”,
deletedKey:“布拉布拉”
}]
var newState=[{
id:2,
foo:‘qux’
}, {
id:3,
傅:“测试”,
补充:“布拉布拉”
}, {
id:3,
foo:“test2”
}, {
id:4,
福:“酒吧”
}];

console.log(getUpdates(old,newState))
谢谢,但你没有读我的第二段。我想要一个从
f
返回的集合,指出发生了什么变化。。。不仅如此,它已经发生了变化。我假设您已经完成了
f(p,n)
,现在只想比较
您在日常工作中如何做到这一点
-通常,我让后端发送更改,而不是整个集合-但这是因为我通常使用的数据集很容易做到。。。你的“收藏”的一个例子肯定会有助于确定最佳行动方案
{id: 2, foo: 'quux'},
{id: 4, foo: 'bar'}
{event: 'removed', id: 1},
{event: 'modified', id: 2},
{event: 'added', id: 4}