【问题标题】:What's the best way to filter an array of objects to only show those objects which were added since the last time it was filtered?过滤对象数组以仅显示自上次过滤后添加的对象的最佳方法是什么?
【发布时间】:2019-05-08 16:58:35
【问题描述】:

我的第一个函数会在我的雇主网站上抓取已完成任务的用户列表,并输出一个包含结果的 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 的解决方案,这样我就可以了解如何在未来更好地驾驭这种情况。但是,如果您也有一个受欢迎的库/模块解决方案。提前致谢。

【问题讨论】:

    标签: javascript arrays object data-structures


    【解决方案1】:

    问题是两个对象永远不相等(除非它们是对同一个对象的引用)。要检查结构是否相等,您必须手动比较它们的属性:

      myArray.filter(el => !toRemove.some(el2 => el.task === el2.task && el.name === el2.name));
    

    虽然这可行,但当您将 myArray 的每个对象与 toRemove 的所有对象进行比较时,对于很多元素来说会很慢。为了改善这一点,您可以从属性中生成一个唯一的散列并将该散列添加到一个集合中:

      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)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多