具有对象包含键数组对的对象嵌套对象的过滤器列表

时间:2019-11-10 15:59:52

标签: javascript arrays filtering javascript-objects

我试图拿出最具描述性的标题。

我想出了一个解决方案,但是它的效率非常低,大约为O(n ^ 4)左右,这很可悲。

我试图根据过滤器对象和匹配的键值过滤并返回对象列表。

我将拥有电影列表docker-compose,并将返回符合movieList对象中包含的所有键值对的所有电影。对于movieFilter,电影必须是流派之一。由于销售不在过滤器中,因此我们不会基于此过滤器。

genre

我遇到的问题是,因为某些过滤器(例如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" }] 过滤器)位于数组中,而某些影片键(例如genre)嵌套在对象中,所以我不得不嵌套循环循环内,这会使时间复杂度增加。

我可以更改过滤器的结构方式,但目前对我来说是有意义的。电影对象格式是我无法更改的。

任何有关如何解决此问题的建议将不胜感激。

2 个答案:

答案 0 :(得分:2)

可以使用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);

更新:

感谢@MkeSpaGuy评论。我已经重新制作了一些方法来过滤您的项目。

它是经过优化的版本,使用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);

答案 1 :(得分:2)

考虑用movieFilter内部的对象替换数组。

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));

但是,请避免使用premature optimization。在现代浏览器中过滤10,000个项目时,您不会注意到优化。
(注意,我说的是过滤器而不是显示)我经常做一些效率较低的事情,而只使用简单,简洁,不变,可读和有用的代码。如果您以功能手机为目标或发现真正的性能瓶颈,则需要使用性能监控工具进行评估。 JavaScript引擎的优化不断改进,结果往往令人惊讶。