if语句的条件元素>数字给出奇怪的结果

时间:2018-04-13 18:51:14

标签: javascript api fetch

好的,标题很一般,但我认为我缺乏正确解释这一点的话。

所以我从外部API获取一些数据,我想过滤一些结果。我使用forEach循环遍历响应,之后使用if语句根据某些条件排除其中一些响应。

所以在这种情况下,我提取了一些电影数据,我想要排除没有img url的电影。这部分工作正常。接下来我想要排除人气水平较低的电影。 json对象上的流行度级别设置为4.45644形式的数字。

const findMovies = response.results;
  findMovies.forEach( movie => {
    if (movie.poster_path != null && movie.popularity > 8) {
       // print to DOM
    } else {
      //dont print nothing
    }

问题在于,使用上面的代码我可以过滤出所有人气较小或大于8的电影。我确定我错过了一些非常愚蠢的东西,但是我已经#0;到目前为止,我花了几个小时的时间。

如果您需要任何其他可能有用的代码段,请告诉我。

这基本上是api响应在控制台上记录的内容

results: Array(20)
  0:
    adult:false
    poster_path: "/tjQHn6xW5BiB1RJ3OZIPDzIOSkF.jpg"
    popularity: 30.400022
    ....

3 个答案:

答案 0 :(得分:3)

以下是我们可以检查的一些代码。我想忘记你现有的代码,并解决问题的关键,即拉出一系列电影并分析它们并以一些自定义的方式对它们进行排序。

我选择使用Array.reduce(),因为它允许我们跨越来自您的数据库的每部电影,并根据我们的感觉分析它,然后创建一个输出对象,过滤匹配的结果并维护一个列表被拒绝的电影。

我这样做是因为我想让你知道reduce是如何运作的(因为它太棒了)

// Simulate the Movie DB
const movies = [
  { title: 'Sammy goes to the store', poster_path: 'http://www.com/photo.jpg', popularity: 2, url: 'http://www.com' },
  { title: 'Sammy doesnt go to the store', poster_path: 'http://www.com/photo.jpg', popularity: 4, url: '' },
  { title: 'Willy goes to Whalemart', poster_path: 'http://www.com/photo.jpg', popularity: 6, url: 'http://www.com' },
  { title: 'Jimmy only had one job', poster_path: 'http://www.com/photo.jpg', popularity: 8, url: '' },
  { title: 'Jimmy no longer has one job', poster_path: 'http://www.com/photo.jpg', popularity: 10, url: 'http://www.com' },
  { title: 'Fred goes to the farm', poster_path: undefined, popularity: 12, url: 'http://www.com' },
  { title: 'Fred doesnt go to the farm', poster_path: 'http://www.com/photo.jpg', popularity: 14, url: '' },
  { title: 'Helga goes to the hackathon', poster_path: 'http://www.com/photo.jpg', popularity: 16, url: 'http://www.com' },
  { title: 'Bhima only had one job', poster_path: 'http://www.com/photo.jpg', popularity: 18, url: '' },
  { title: 'Bhima no longer has one job', poster_path: null, popularity: 20, url: 'http://www.com' },
]

// Simulate the network request to get the movies
const response = { results: movies }

// Start with your existing code
const findMovies = response.results

// Rather than forEach, we will use Array.map() or Array.reduce()
// and set the filtered results into a new Array,
// because it provides you more utility overall
const filteredMovies = findMovies.reduce((acc, movie) => {
  if (movie.poster_path == null) {
    // console.log('REJECTING:', movie, 'REASON: no photo')
    movie.rejectReason = 'no photo'
    acc.rejects.push(movie)
    return acc
  }
  if (movie.popularity < 8) {
    // console.log('REJECTING:', movie, 'REASON: bad rating')
    movie.rejectReason = 'bad rating'
    acc.rejects.push(movie)
    return acc
  }
  acc.matches.push(movie)
  return acc
}, { matches: [], rejects: [] })

console.log('MATCHES', filteredMovies.matches)

console.log('\nREJECTS', filteredMovies.rejects)

首先,Array.map()Array.reduce()Array.forEach()非常相似。如果你已经知道这一点,太棒了 - 我爱你。他们三个都跨过一个迭代,并对每个项目做一些事情。区别在于map生成一个新的Array并且reduce可以生成任何数据结构。这使得流程不可变和良好做法。你必须自己研究不变性。如果这样做,请注意JavaScript如何维护对非基元的实时引用。当涉及“共享可变状态”时,这可能会产生噩梦。

其次,Array.reduce()比map更多,因为它是一个累加器。如果你不熟悉,我非常推荐学习所有关于减少的知识。简而言之,在我的示例中,我们正在累积一个具有两个键的对象:matchesrejects。我们正在逐步完成电影阵列中的每个项目并使用您原来的逻辑对其进行分析,但我将其翻转到您所拥有的相反的位置。它是这样的:

1)检查每部电影

2)如果movie.poster_path == null:movie是拒绝,请将其推入我们正在累积的拒绝数组中。使用==会捕获所有虚假值,例如''0undefinednull

3)如果movie.popularity < 8:movie是拒绝,请将其推入我们正在累积的拒绝数组中。

4)在我们移动到列表中的下一部电影之前,我们在电影结果中添加rejectReason属性(以防我们稍后要检查它或在错误消息中显示它)。

5)注意reduce函数是如何导致拒绝的if语句列表,最后一步说:“如果电影还没有被拒绝,请将它添加到我们正在积累的matches数组中

加分备注acc代表累加器。如果你仔细观察,我们正在积累一些东西,而reduce函数循环遍历每个项目。当它说return acc时。这意味着,返回累加器,以便下一个项目也可以使用它。

由于您在这个问题上花了很长时间,我想帮助您了解如何考虑进行这种“从列表到过滤集的转换”。我使用并提倡函数式编程技术。 map,filter和reduce是这种思维方式的核心,因此是不可变数据结构,通常是数据流的一种方式。请注意我丢弃的这些关键字,并在人们谈论它们时始终注意。当你在复杂的应用程序中进行更多疯狂的异步事件处理时,这些东西将变得越来越有吸引力。

答案 1 :(得分:1)

试试这个

  const findMovies = response.results;
    findMovies.forEach( movie => {
      if (movie.poster_path != null && (8-movie.popularity> 0d)){
         // print to DOM
      } else {
         //dont print anything
      }

答案 2 :(得分:0)

您也可以尝试:

const result = findMovies.filter(movies => movies.popularity > 8);
console.log(result);

这将过滤数组的最终结果是只返回流行度大于8的电影。然后你可以在结尾使用.forEach()来迭代结果,如果你只是寻找某些键等的值