我的第一个功能会在我的雇主网站上抓取一个已完成任务的用户列表,并输出一个包含结果的json文件。 json文件的组织方式如下:
{"Completed":[{"task":"TitleOfTaskAnd01/01/2019", "name":"UsersFullName"},{"task":"TitleOfTaskAnd01/01/2019", "name":"UsersFullName"}...]}
我的第二个功能使用上述json文件自动生成收据。再次调用这两个函数时,我想保留以前使用的所有数据,而只为那些先前调用的结果中没有的任务生成收据,从而避免了重复的生成。
我试图用第二个数组的元素过滤第一个数组,但是据我所知,您不能比较对象,甚至不能比较数组。这是我尝试根据需要调整的功能:
let myArray = myArray.filter( ( el ) => !toRemove.includes( el ) );
我希望我的用例并不太常见,并且在这种情况下已经有很多有关最佳实践的经验。我更喜欢只使用javascript的解决方案,以便将来了解如何更好地解决这种情况。但是,如果您有一个库/模块解决方案也受到欢迎。预先感谢。
答案 0 :(得分:1)
问题在于两个对象永远不相等(除非它们是对同一对象的引用)。要检查结构是否相等,您必须手动比较它们的属性:
myArray.filter(el => !toRemove.some(el2 => el.task === el2.task && el.name === el2.name));
虽然可行,但将myArray的每个对象与toRemove的所有对象进行比较时,许多元素的运行速度将非常慢。为了改善这一点,您可以从属性中生成唯一的哈希,然后将该哈希添加到Set中:
const hash = obj => JSON.stringify([obj.name, obj.task]);
const remove = new Set(toRemove.map(hash));
const result = myArray.filter(el => !remove.has(hash(el)));
这将是O(n + m),而先前的解决方案是O(n * m)。