从第二个数组中过滤匹配值的对象数组

Posted

技术标签:

【中文标题】从第二个数组中过滤匹配值的对象数组【英文标题】:Filter array of objects matching values from second array 【发布时间】:2021-03-21 02:46:07 【问题描述】:

在我的 react 应用中,我的用户看起来像这样:

 username: 'admin', genres: [name: 'Music', id: 1, name: 'Art', id: 2] 

还有像这样的视频:

 title: 'cool video', genres: [name: 'Music', id: 1, name: 'Technology', id: 3] 

我正在尝试编写一个函数,该函数将返回一个包含单个用户内任何类型的视频对象数组。到目前为止,我已经能够硬编码一个解决方案,但是如果用户的类型数量错误,它就会中断,所以我正在寻找一个更简洁的解决方案。这是我目前所拥有的:

function filterVideos() 

const userGenres = []

user.genres.forEach(genre => 
  userGenres.push(genre.name)
)

const filteredVideos = videos.filter(video => 

  return video.genres.find(o => o.name === userGenres[0])
   || video.genres.find(o => o.name === userGenres[1])
   || video.genres.find(o => o.name === userGenres[2])
)
return filteredVideos

【问题讨论】:

这能回答你的问题吗? How filter array of objects by another array of objects [ES6] 【参考方案1】:

如果我理解您的问题,您希望返回经过过滤的完整视频对象数组,这些对象与传递的用户至少有一个共同的流派。

您可以使用单个 map() 调用将用户的流派数组简化为流派名称数组。

const userGenres = user.genres.map((name) => name);

然后使用Array.prototype.some() 来确定视频的任何类型是否包含在使用Array.prototype.includes()userGenres 数组中

 videos.filter(video => (
    video.genres.some((name) => userGenres.includes(name))
  ));

const user =  
  username: 'admin',
  genres: [name: 'Music', id: 1, name: 'Art', id: 2] 

const videos = [
  
    title: 'video1', 
    genres: [name: 'Music', id: 1, name: 'Technology', id: 3] 
  ,
  
    title: 'video2', 
    genres: [name: 'Art', id: 1, name: 'Technology', id: 3] 
  ,
  
    title: 'video3', 
    genres: [name: 'Sports', id: 1, name: 'Technology', id: 3, , name: 'Skiing', id: 3] 
  
]

function filterVideos(user, videos) 

  const userGenres = user.genres.map((name) => name);
  
  return videos.filter(video => (
    video.genres.some((name) => userGenres.includes(name))
  ));
  


console.log(filterVideos(user, videos));

【讨论】:

【参考方案2】:

您可以在filter 中使用some()

const filteredVideos = videos.filter(video => user.genres.some(gen => gen.name === video.name))

const user =  username: 'admin', genres: [name: 'Music', id: 1, name: 'Art', id: 2] 
const video =  title: 'cool video', genres: [name: 'Music', id: 1, name: 'Technology', id: 3] ;

const res = video.genres.filter(v => user.genres.some(g => g.name === v.name));
console.log(res)

【讨论】:

您可以使用id 代替name。我认为这可能是更好的主意 @AlexeyZelenin 您的观点是有效的,但 OP 要求是比较 name 你确定user 部分吗?因为我认为他有一个users 数组而不是一个user 对象? @AlanOmar 我也在考虑这个,但他还没有提到任何事情。我只是将他的方法重构为更简单。让我们看看 OP 是如何应对的 感谢大家的回复!我认为 id 或 name 本来是可行的,但我希望像 Pilchard 的解决方案一样返回整个视频对象! (我可能没有很好地解释自己!)不过真的很感谢你的帮助! :)

以上是关于从第二个数组中过滤匹配值的对象数组的主要内容,如果未能解决你的问题,请参考以下文章

使一个数组等于特定对象的另一个数组

按匹配不同数组的属性过滤字典数组

从数组中过滤对象,具有匹配两个值的差异

比较两个数组并查找第二个数组中缺少的项目[重复]

循环遍历python数组以匹配第二个数组中的多个条件,快速方法?

通过索引从数组中获取对象,即从另一个数组中获取