简体   繁体   English

使用包含键数组对的 Object 过滤对象嵌套对象列表

[英]Filter List of Object-Nested Objects with Object Containing Key-Array Pair

I tried to came up with the most descriptive title.我试图想出一个最具描述性的标题。

I came up with a solution but its terribly inefficient as its in the order of O(n^4) or so, which is pathetic.我想出了一个解决方案,但它的效率非常低,因为它的顺序是 O(n^4) 左右,这很可悲。

I am trying to filter and return a list of objects based on a filter-object and matching key values.我正在尝试根据过滤器对象和匹配的键值过滤并返回对象列表。

I will have a list of movies, movieList , and I will return all movies that meet all the key-value pairs that are contained within the movieFilter object.我将有一个电影列表movieList ,并且我将返回满足包含在movieFilter object 中的所有键值对的所有电影。 In the case of genre , the movie must be one of the genres.genre的情况下,电影必须是流派之一。 Since sales is not in the filter we do not filter based on it.由于销售额不在过滤器中,因此我们不会根据它进行过滤。

let movieFilter = {
  "genre": ["Action", "Romance"],
  "director": "Bob",
  "writer": ["Jim", "Dave", "Alice"],
  "duration": "2"
}

let movie = {
  "genre" : "Action",
  "people": {
    "director": "Bob",
    "writer": "Alice"   
  }
  "boxoffice": "9,000,000",
  "duration": "2"
}

let movies = [{
  "genre" : "Action",
  "people": {
    "director": "Bob",
    "writer": "Alice"   
  }
  "boxoffice": "9,000,000",
  "duration": "2"
}, 
{
  "genre" : "Comedy",
  "people": {
    "director": "Rose",
    "writer": "Mike"   
  }
  "boxoffice": "12,000,000",
  "duration": "3"
}]

The issue I'm having is that because some filters (like the genre filter) are in arrays and some movie keys (like people ) are nested within an object I am forced to nest loops within loops, which makes the time complexity grow.我遇到的问题是,因为一些过滤器(如genre过滤器)在 arrays 中,而一些电影键(如people )嵌套在 object 中,我被迫在循环中嵌套循环,这使得时间复杂度增加。

I could change the way the filter is structures, but the way it currently is makes sense to me.我可以改变过滤器的结构方式,但它目前的方式对我来说是有意义的。 The movie object format is something I cannot change.电影 object 格式是我无法更改的。

Any suggestion on how I could tackle this would be appreciated.任何关于我如何解决这个问题的建议将不胜感激。

It can be done using filter method and some method:可以使用filter方法和some方法来完成:

 let movieFilter = { "genre": ["Action", "Romance"], "director": "Bob", "writer": ["Jim", "Dave", "Alice"], "duration": "2" } let movies = [ { "genre": "Action", "people": { "director": "Bob", "writer": "Alice" }, "boxoffice": "9,000,000", "duration": "2" }, { "genre": "Comedy", "people": { "director": "Rose", "writer": "Mike" }, "boxoffice": "12,000,000", "duration": "3" }] const result = movies.filter(f => movieFilter.genre.some(ge=> ge == f.genre) && movieFilter.director == f.people.director && movieFilter.writer.some(wr => wr == f.people.writer) && movieFilter.duration == f.duration ); console.log(result);

UPDATE:更新:

Thanks to @MkeSpaGuy comment.感谢@MkeSpaGuy 评论。 I've remade a little bit approach to filter your items.我已经重新设计了一些过滤您的项目的方法。

It is slightly optimized version using key to check whether filter conditions are satisfied:略优化版本,使用key检查过滤条件是否满足:

 let movieFilter = { "genre": ["Action", "Romance"], "director": "Bob", "writer": ["Jim", "Dave", "Alice"], "duration": "2" } movieFilter.genre = movieFilter.genre.reduce((a, key) => ({...a, [key]: 1}), {}); movieFilter.writer = movieFilter.writer.reduce((a, key) => ({...a, [key]: 1}), {}); let movies = [{ "genre": "Action", "people": { "director": "Bob", "writer": "Alice" }, "boxoffice": "9,000,000", "duration": "2" }, { "genre": "Comedy", "people": { "director": "Rose", "writer": "Mike" }, "boxoffice": "12,000,000", "duration": "3" }]; const result = movies.filter(f => movieFilter.genre[f.genre] && movieFilter.director == f.people.director && movieFilter.writer[f.people.writer] && movieFilter.duration == f.duration ); console.log(result);

Consider replacing your arrays with objects inside your movieFilter.考虑用你的movieFilter中的对象替换你的arrays。

 let movieFilter = { genre: { Action: true, Romance: true }, director: "Bob", writer: { Jim: true, Dave: true, Alice: true }, duration: "2" }; let movies = [ { genre: "Action", people: { director: "Bob", writer: "Alice" }, boxoffice: "9,000,000", duration: "2" }, { genre: "Comedy", people: { director: "Rose", writer: "Mike" }, boxoffice: "12,000,000", duration: "3" } ]; const filterOnMovieFilter = movie => { const { genre, people, duration } = movie; const { writer, director } = people || {}; return ( movieFilter.genre[genre] && movieFilter.writer[writer] && movieFilter.duration === duration && movieFilter.director === director ); }; console.log(movies.filter(filterOnMovieFilter));

However, please avoid premature optimization .但是,请避免过早优化 You will not notice optimization when filtering 10,000 items in a modern browser.在现代浏览器中过滤 10,000 个项目时,您不会注意到优化。
(Notice I said filter and not display) I often do things that are less efficient in favor of simple, concise, immutable, readable and useful code. (注意我说的是过滤而不是显示)我经常做一些效率较低的事情,以支持简单、简洁、不可变、可读和有用的代码。 If you are targeting a feature phone or find a real performance bottleneck, you will need to measure with performance monitoring tools.如果您的目标是功能手机或发现真正的性能瓶颈,则需要使用性能监控工具进行测量。 The JavaScript engine optimizations are continuously improving and results are often surprising. JavaScript 引擎优化不断改进,结果往往令人惊讶。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM