从两个数组中过滤重复项

Posted

技术标签:

【中文标题】从两个数组中过滤重复项【英文标题】:Filtering duplicates from two arrays 【发布时间】:2020-08-26 06:41:31 【问题描述】:

我正在尝试...

responseData.posts 和 fbFormattedPosts 都是 post 对象的数组。一些帖子出现在两个数组中,具有相同的“postId”。我想将我的状态设置为包含 responseData.posts 的所有帖子的数组......然后我想将 fbFormattedPosts 添加到该数组中 - 但我不想包含具有相同“postId”的 fbFormattedPosts。

我使用 useState 函数 setPosts 设置了我的“帖子”useState 数组。如果我为它们使用扩展运算符,它们都会添加每个数组中的所有帖子。这行得通,但我最终得到了重复的帖子。

//set All Posts
        setPosts([ ...responseData.posts, ...fbFormattedPosts])

所以,我正在尝试比较 Id 以将它们过滤掉。

setPosts([ ...responseData.posts, fbFormattedPosts.forEach(fbPost => 
            responseData.posts.filter(resPost => 
                if(fbPost.postId !== resPost.postId )
                    return fbPost
                
            )
        )])

显然这不起作用......现在我根本没有收到任何帖子。甚至没有 responseData.posts。

【问题讨论】:

【参考方案1】:

按照您的逻辑,应根据 responseData.posts 中缺少的 postId 过滤 fbFormattedPosts,因此您只需查找匹配项(例如,使用某些方法,如 Array.prototype.find()Array.prototype.some(),即在Array.prototype.filter() 内将被评估为真并在匹配后立即退出)并且不要忘记传播过滤器的结果(使用...):

setPosts([ 
   ...responseData.posts, 
   ...fbFormattedPosts
      .filter(fbPost => 
         !responseData.posts
            .find(post => 
               post.postId == fbPost.postId
            )
      )
])

【讨论】:

这个有效!稍后我将有时间坐下来弄清楚为什么会这样...... 我迷失了 .filter() 的参数 - 看起来你正在解构 postId... 那么 !responseData.posts.find()... 是如何工作的?跨度> @NickMcLean :我在filter() 回调的范围内解构postId,因此它相当于在比较时具有等于fbFormattedPosts 给定项目的当前postId 的变量(在同一范围内)与post.postIdresponseData.posts @NickMcLean :我已经删除了解构以消除混乱的根源,它应该仍然有效;) 非常感谢您的帮助和解释。我想我开始明白这一点了!我只做过 .filter() 与单个值比较的数组。 Dang 这个太酷了 - 再次感谢!【参考方案2】:

如果你想以函数的方式传播数组,你应该使用数组filter和some:

setPosts([ ...responseData.posts, ...fbFormattedPosts.filter(fbPost => (
            !responseData.posts.some(resPost =>
                fbPost.postId === resPost.postId 
            )
        ))])

【讨论】:

【参考方案3】:

你的主要想法是正确的,但你没有以正确的方式去做。您需要在添加之前过滤您的fbFormattedPostsArray.every 测试数组中的所有元素是否通过提供的函数实现的测试。 Array.filter剪切所有every返回false的元素

setPosts([ ...responseData.posts, fbFormattedPosts.filter(fbPost => 
        return responseData.posts.every(resPost => 
            return fbPost.postId !== resPost.postId
        )
    )])

【讨论】:

以上是关于从两个数组中过滤重复项的主要内容,如果未能解决你的问题,请参考以下文章

从数组中删除所有某些重复项[重复]

如何从 Javascript 中的数组中删除重复项?

删除数组中的重复项

如何使用两个键删除数组中的重复项?

从数组中删除重复项会在最终结果中留下重复值

如果两个值匹配,则从 php 中的多维关联数组中删除重复项