当前位置: 首页 > 知识库问答 >
问题:

Javascript:从API调用中过滤JSON对象,只获取我需要的信息

裴浩歌
2023-03-14

我正在尝试创建一个小项目来处理API调用。我已经创建了一个异步,它使用MusicBrainz API恢复有关曲目的信息。您可以通过单击此处来检查请求的结果:https://musicbrainz.org/ws/2/recording/5935ec91-8124-42ff-937f-f31a20ffe58f?inc=genres 收视率释放艺术家

以下是我迄今为止对我的请求的JSON响应的修改:

export const GET_JSON = async function (url) {
  try {
    const res = await Promise.race([
      fetch(url),
      timeout(CONSTANTS.TIMEOUT_SEC),
    ]);
    const data = await res.json();

    if (!res.ok) throw new Error(`${data.message} (${res.status})`);
    return data;
  } catch (err) {
    throw err;
  }
};
export const loadTrackDetail = async function (id) {
  try {
    const trackData = await GET_JSON(
      encodeURI(
        `${CONSTANTS.API_URL}${id}?inc=genres+artists+ratings+releases&fmt=json`
      )
    );
    details.trackDetails = {
      trackTitle: trackData.title,
      trackID: trackData.id,
      trackLength: trackData.length ?? "No duration provided",
      trackArtists: trackData["artist-credit"].length
        ? trackData["artist-credit"]
        : "No information on artists",

      trackReleases: trackData["releases"].length
        ? trackData["releases"]
        : "No information on releases",

      trackGenres: trackData["genres"].length
        ? trackData["genres"]
        : "No information on genres",
      trackRating: trackData.rating.value ?? "No rating yet",
    };

    console.log(details.trackDetails);
  } catch (err) {
    throw err;
  }

现在这还不错,但releases属性(例如)是一个对象数组(每个对象都是轨迹所在的特定版本),但对于每个版本,我只想将对象“减少”为其id和标题。其余的我不感兴趣。此外,我想说的是,例如,如果一个版本的标题类似于已经存在的前一个版本的标题,则不会将整个对象添加到新数组中。我曾考虑过使用foreach函数,但我就是不知道如何正确编写它,如果可能的话,比如我应该使用array.map,或者其他迭代方法。如果有人能在纯JS(不是Jquery!)中高效、干净地实现这一点,那将不胜感激!

干杯

共有3个答案

燕光熙
2023-03-14

数组details.trackDetails.trackReleases具有从不同对象指向idname的路径。如果您的意思是:[“发布事件”]=

演示在每一级路径上使用flatMap()提取“释放事件”,然后使用“区域”返回一个对象数组

[{name: area.name, id: area.id}, {name: area.name, id: area.id},...]

然后将对数组运行到一个for…of循环中,并将每个唯一的名称id设置为ES6映射。然后它将贴图作为对象返回。

{name: id, name: id, ...}

要查看此功能,请转到此Plunker

js prettyprint-override">const releaseEvents = (details.trackDetails.trackReleases) => {
  let trackClone = JSON.parse(JSON.stringify(objArr));
  let areas = trackClone.flatMap(obj => {
    if (obj["release-events"]) {
      let countries = obj["release-events"].flatMap(o => {
        if (o["area"]) {
          let area = {};
          area.name = o["area"]["name"];
          area.id = o["area"]["id"];
          return [area];
        } else {
          return [];
        }
      });
      return countries;
    } else {
      return [];
    }
  });
  let eventAreas = new Map();
  for (let area of areas) {
    if (!eventAreas.has(area.name)) {
      eventAreas.set(area.name, area.id);
    }
  }
  return Object.fromEntries([...eventAreas]);
};

console.log(releaseEvents(releases));
阚英武
2023-03-14
const releasesReduced = []
const titleNotExist = (title) => {
    return releasesReduced.every(release => {
        if(release.title === title) return false;
        return true
    })
}
trackData["releases"].forEach(release => {
    if (titleNotExist(release.title))
        releasesReduced.push({id: release.id, title: release.title})
})
console.log(releasesReduced)
邴景山
2023-03-14

有一些事情让这个问题有点难以回答,但我相信下面的内容会让你指向正确的方向。

  1. 您没有包含GET_JSON方法,因此您的示例不完整,无法立即用于迭代。
  2. 在您带来的示例中,releases数组中包含的对象没有name属性。我用下面的标题替换了名称,以演示该方法
  3. 你说

此外,我想说,例如,如果一个版本的名称与已经存在的前一个版本的名称相似,则整个对象不会添加到新数组中。

但你没有定义你认为会使发行版本相似的内容。

鉴于上述情况,如前所述,我假设你说名字时是指标题,我也假设构成类似版本的是具有相同名称/标题的版本。

假设这些假设是正确的,我只是获取结果。响应上有一个json方法,该方法将响应转换为json对象。I将每个版本映射到您感兴趣的较小的数据集(id、title),然后减少该数组以删除“重复”版本。

js lang-js prettyprint-override">fetch('https://musicbrainz.org/ws/2/recording/5935ec91-8124-42ff-937f-f31a20ffe58f?inc=genres+ratings+releases+artists&fmt=json')
.then(m => m.json())
.then(j => {
  const reducedReleases = j.releases
                           .map(release => ({ id: release.id, name: release.title }))
                           .reduce(
                            (accumulator, currentValue, currentIndex, sourceArray) => {
                              if (!accumulator.find(a => a.name === currentValue.name)) {
                                accumulator.push(currentValue);
                              }
                              
                              return accumulator;
                            },
                            []);
  console.log(reducedReleases);
 });
 类似资料:
  • 问题内容: 我在从此api阅读时遇到麻烦 http://api.xhanch.com/islamic-get-prayer- time.php?lng=67&lat=24&yy=2012&mm=7&gmt=5&m=json 这是我的代码: 此方法始终返回空白字符串,而不是我需要的信息。 问题答案: 这为你提供了一个可行的例子

  • 问题内容: 在viewmodel对象中,以下是属性: 在VIEW中,javascript如下: 请在这里指导,我如何在javascript中获取JSON对象。 问题答案: 您可以使用以下内容: 这将输出以下内容(没有看到您的模型,我仅包含一个字段): 工作小提琴 AspNetCore AspNetCore使用的接口 MVC 5/6 您可以为此使用Newtonsoft: 这使您可以更好地控制json

  • 我有一个API,它返回的数据类型为_HttpClientResponse,因为我使用的是httpClient,我使用下面的 当我打印结果i/flatter(23708):字符串i/flatter(23708):{“结果”:[{“IPAddress”:“192.1.1.1”,“说明”:“Windows 2016 Server”},{“IPAddress”:“192.1.1.1”,“说明”:“Wind

  • 我应该如何删除列表中所有不符合条件的子对象并获得新的列表。

  • 问题内容: 我正在获取一个文本文件并填充一个arraylist。为了测试文件,我在继续之前将其打印出来。我只能从文件中看到内存地址,而不能看到实际信息。有什么简单的东西,也许很明显我想念吗? 测试员 问题答案: 有什么简单的东西,也许很明显我想念吗? 是的- 你没有覆盖的,所以你得到的默认实现: Object类的toString方法返回一个字符串,该字符串包括该对象是其实例的类的名称,符号字符“

  • 问题内容: 这是我要在这里实现的目标: 从数据库获取文件名和ID的列表 在网络路径上搜索这些文件 存储未找到的文件的任何ID 在第二个数据库中搜索该ID 在网络路径上搜索这些文件 列出所有在两个位置均未找到文件的ID。 我遇到的问题是尝试使用我收集的结果中的文件名。 运行代码时,会显示从数据库收集的原始JSON数据,但是当尝试仅列出文件名时,我什么也没得到(甚至没有错误) 关于如何解决此问题并以一