如何使用 Javascript(适用于 Google Sheets)过滤嵌套 JSON 数组的条件并仅从过滤器的第一个结果返回一个值?

问题描述 投票:0回答:1

我正在使用 TMDB api 将电影数据提取到 Google 表格中。此 Google 表格是根据 Reddit 用户 6745408 的“MediaSheet 3.0”重新设计的。该表使用基于 Javascript 的脚本。我已经能够通过遵循原始脚本中使用的模式/代码来提取原始脚本/表中没有的键的值。但是,我不知道如何执行以下操作:

“results”键内嵌套有多个数组。嵌套在“结果”下的每个数组都是与该电影标题关联的视频。我想要返回到 Google Sheet 的是以(“key”)结尾的 url。不过,我只希望将一个视频网址/“密钥”返回到 Google 表格中,我希望脚本过滤具有值 (“site”: “YouTube”) 和 (“type”: "trailer) OR ("type": "teaser") 然后从那里返回过滤器的第一个结果并返回该视频的("key")。

这是我尝试从 TMDB api 解析的 JSON 数据:

{
  "id": 290098,
  "results": [
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "In the Projection Booth - Park Chan-wook, director of The Handmaiden (contains spoilers)",
      "key": "P8g8QJk96M4",
      "site": "YouTube",
      "size": 1080,
      "type": "Featurette",
      "official": true,
      "published_at": "2017-04-14T08:30:01.000Z",
      "id": "65be6283902012012fc9a5a7"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "UK Promo",
      "key": "xX7HsdfIYGw",
      "site": "YouTube",
      "size": 1080,
      "type": "Teaser",
      "official": true,
      "published_at": "2017-03-31T16:51:17.000Z",
      "id": "65be628efc6538017cea4ee3"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "UK Trailer",
      "key": "wYsdzNIcJNc",
      "site": "YouTube",
      "size": 1080,
      "type": "Trailer",
      "official": true,
      "published_at": "2017-03-09T12:54:54.000Z",
      "id": "65be625ea7e363018454330d"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "Extended Preview",
      "key": "5bOWrDriBno",
      "site": "YouTube",
      "size": 1080,
      "type": "Clip",
      "official": true,
      "published_at": "2017-01-17T17:49:04.000Z",
      "id": "65be613143999b0184c5d86e"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "Dress Up (Movie Clip)",
      "key": "y43Y20jdctw",
      "site": "YouTube",
      "size": 1080,
      "type": "Clip",
      "official": true,
      "published_at": "2016-10-24T21:00:04.000Z",
      "id": "65be60b512c604017c0096e5"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "The House (Movie Clip)",
      "key": "jUP3cPWQBh4",
      "site": "YouTube",
      "size": 1080,
      "type": "Clip",
      "official": true,
      "published_at": "2016-10-24T17:44:18.000Z",
      "id": "65be60bca7e36301b7547dcd"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "The Library (Movie Clip)",
      "key": "gvijQuKBz88",
      "site": "YouTube",
      "size": 1080,
      "type": "Clip",
      "official": true,
      "published_at": "2016-10-24T01:44:31.000Z",
      "id": "65be60c4031deb0162ee63e3"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "The Kiss (Movie Clip)",
      "key": "6ir3_NoTJOw",
      "site": "YouTube",
      "size": 1080,
      "type": "Clip",
      "official": true,
      "published_at": "2016-10-22T17:00:18.000Z",
      "id": "65be60cca7e363013653c57c"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "The Bath (Movie Clip)",
      "key": "O4p9o3aJGj8",
      "site": "YouTube",
      "size": 1080,
      "type": "Clip",
      "official": true,
      "published_at": "2016-10-21T17:00:08.000Z",
      "id": "65be60d443999b0163c50b39"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "Official US Trailer",
      "key": "whldChqCsYk",
      "published_at": "2016-07-29T17:02:31.000Z",
      "site": "YouTube",
      "size": 1080,
      "type": "Trailer",
      "official": true,
      "id": "57dbf0eb925141684c008ae7"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "Official International Trailer",
      "key": "NoyWKl0e8FI",
      "published_at": "2016-05-03T06:15:07.000Z",
      "site": "YouTube",
      "size": 1080,
      "type": "Trailer",
      "official": true,
      "id": "57dbf22b9251416905008c72"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "Official Int'l Special Trailer",
      "key": "6sVYumzrKvs",
      "published_at": "2016-04-25T12:39:44.000Z",
      "site": "YouTube",
      "size": 1080,
      "type": "Trailer",
      "official": true,
      "id": "571e5a939251416f2c0003f0"
    }
  ]
}

这是我正在 Google Sheets 应用程序脚本中处理的代码:

function TMDBmovietrailer123(rows) {
  var tmdbKey = PropertiesService.getScriptProperties().getProperty('tmdbkey');
  const requests = rows.map(id => {
    return {
      url: `https://api.themoviedb.org/3/movie/${id}/videos?api_key=${tmdbKey}`,
      muteHttpExceptions: true
    }
  })
  const responses = UrlFetchApp.fetchAll(requests)
  return responses.map(request => {
    try {
      const data = JSON.parse(request.getContentText());
      const id = data.id

      return [id]
    } catch (err) {
      return ['']
    }
  })
}
javascript arrays json google-sheets google-apps-script
1个回答
0
投票

results
是一个匿名对象数组,仍然可以在其上使用
filter
,但对于您的用例,Arrayfind 方法可能是最合适的。这是因为
filter
在找到一个项目后将继续遍历数组,而
find
将在找到第一个元素后立即停止。

考虑到包含

id
+
results
的对象是
response
,可以这样做(响应数据最小化以提高可读性):

const response = {
  "id": 290098,
  "results": [
    {
      "key": "P8g8QJk96M4",
      "site": "YouTube",
      "type": "Featurette"
    },
    {
      "key": "xX7HsdfIYGw",
      "site": "YouTube",
      "type": "Teaser"
    },
    {
      "key": "wYsdzNIcJNc",
      "site": "YouTube",
      "type": "Trailer"
    },
    {
      "key": "5bOWrDriBno",
      "site": "YouTube",
      "type": "Clip"
    }
  ]
}


const trailer = response.results.find((o) => (o?.site === 'YouTube') && (o?.type === 'Trailer' || o?.type === 'Teaser'))

console.log(trailer?.key || 'not found')

这可以扩展到使用

typeof o.<property> !== 'undefined' && o.<property> === 'value'

© www.soinside.com 2019 - 2024. All rights reserved.