【问题标题】: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}

【问题讨论】:

标签: javascript arrays reactjs object filter


【解决方案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 的解决方案一样返回整个视频对象! (我可能没有很好地解释自己!)不过真的很感谢你的帮助! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多