[英]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.