从 API Javascript 内的嵌套数据结构中检索多个值
Retrieve multiple values from nested data structures within API Javascript
我重新设置了这个问题的格式以正确显示问题并显示我之前为获得所需结果所做的尝试。
下面是来自 rapid.api 的 NBA API 回复 这个具体的回复 (https://api-nba-v1.p.rapidapi.com/games/live/) 吐出了目前 live/ongoing 的当前 NBA 比赛。
我正在使用此 API 和其他各种回复,以直接的方式检索 NBA 信息。 我的脚本是为 Discord 设计的。
在我拥有的这个 Discord 服务器中,我们为每场 NBA 比赛制作频道,以便用户可以讨论它。我一直在尝试制作一个显示当前游戏分数的分数命令。
我的issue/goal:
我一直在努力寻找一种方法;
- 通过球队的昵称匹配频道名称(游戏频道名称的示例是:lakers-vs-nets),这将让我确保我得到正确游戏的分数
- 从主队和客队中检索比分
- 打印主队和客队的比分。
我不熟悉 APIs 并试图更好地使用它们,并且我已经学会了更多创造性的方式来使用 Javascript。因此,我们将不胜感激对此问题的任何帮助和解释;谢谢。
"api":{
"status":200
"message":"GET games/live"
"results":4
"filters":[
0:"seasonYear"
1:"league"
2:"gameId"
3:"teamId"
4:"date"
5:"live"
]
"games": [
0: {
"seasonYear":"2021"
"league":"standard"
"gameId":"10187"
"startTimeUTC":"2022-01-13T00:30:00.000Z"
"endTimeUTC":""
"arena":"Madison Square Garden"
"city":"New York"
"country":"USA"
"clock":"1:35"
"gameDuration":"2:05"
"currentPeriod":"4/4"
"halftime":"0"
"EndOfPeriod":"0"
"seasonStage":"2"
"statusShortGame":"2"
"statusGame":"In Play"
"vTeam":{
"teamId":"8"
"shortName":"DAL"
"fullName":"Dallas Mavericks"
"nickName":"Mavericks"
"logo":"https://upload.wikimedia.org/wikipedia/fr/thumb/b/b8/Mavericks_de_Dallas_logo.svg/150px-Mavericks_de_Dallas_logo.svg.png"
"score": {
"points":"82"
}
}
"hTeam":{
"teamId":"24"
"shortName":"NYK"
"fullName":"New York Knicks"
"nickName":"Knicks"
"logo":"https://upload.wikimedia.org/wikipedia/fr/d/dc/NY_Knicks_Logo_2011.png"
"score":{
"points":"121"
}
}
1: {
"seasonYear":"2021"
"league":"standard"
"gameId":"10189"
"startTimeUTC":"2022-01-13T02:00:00.000Z"
"endTimeUTC":""
"arena":"Vivint Arena"
"city":"Salt Lake City"
"country":"USA"
"clock":"8:08"
"gameDuration":"1:46"
"currentPeriod":"4/4"
"halftime":"0"
"EndOfPeriod":"0"
"seasonStage":"2"
"statusShortGame":"2"
"statusGame":"In Play"
"vTeam":{...}
"hTeam":{...}
]
}
}
vTeam 和 hTeam 在这里折叠以压缩代码,但它应该让您了解响应,因为它与之前的几乎相同,只是不同的团队、分数等。
这是我到目前为止尝试过的一些代码:
function iterationObject(obj) {
for(prop in obj) {
// If Object
if (typeof(obj[prop]) == "object"){
// Push
iterationObject(obj[prop]);
} else {
/* This only seems to work if I run solely search for the keys and not the values. So for example, this would work:
if (prop == "nickName" || prop == "shortName"){
console.log(prop + ': ', obj[prop])
}
^ This would work and print the values from anything matching nickName and shortName keys (so in this case, it would print every nickName and shortName it found.*/
if (prop == "nickName" && obj[prop] == "Knicks"){
console.log(prop + ': ', obj[prop])
// ^ This is the last thing that I have tried, but has been returning undefined.
}
}
}
}
case 'gamescore':
var gamescoreurl = "https://api-nba-v1.p.rapidapi.com/games/live/";
axios.get(gamescoreurl, {
headers: {
"x-rapidapi-key": apikey,
"x-rapidapi-host": apihost
}
}).then(response=> {
/* Something I tried with .find, only seems to search surface level with the response. What I mean by that is,
I can dive into games API response, but I can't go games.hTeam with .find
var firstchannelpart = message.channel.name
var gamechannelfinder = firstchannelpart.split("-")[0];
var gameapiresp= response.data.api.games
const hscore = gameapiresp.find(el => {
return el.nickName== gamechannelfinder
})
console.log(hscore)
*/
// My latest attempt, which works retrieving specific values that match using prop as a var in iterationObject. Also, the item variable returns as undefined here, but iterationObject will print from the console what it is supposed to.
tidobj.filter(item => {
iterationObject(item)
})})
break;
你可以看到我发表了一些评论,这些评论仅供本帖帮助理解我之前的尝试,但我觉得其中一个可能就在正确的边缘。
根据上面列出的 API 结果,您可以做类似的事情,
// Set up our sample vars
let channelName = "Mavericks-vs-Knicks";
let gamescoreurl = "https://api-nba-v1.p.rapidapi.com/games/live/";
// Make Axios Call
axios.get(gamescoreurl, {
headers: {
"x-rapidapi-key": apikey,
"x-rapidapi-host": apihost
}
}).then(results => {
// get array of team names to pass to 'LogGameScores'
let teamNickNames = GetTeamsFromChannelName(channelName);
// Log the game scores
LogGameScores(teamNickNames, results?.games);
})
这是一个从频道名称中获取团队名称的简单函数。
function GetTeamsFromChannelName(name = "channelName") {
return name.split("-vs-"); // Split the team Nick Names from the channel name
}
以及获取/记录分数的方法
function LogGameScores(teams = [], games = null) {
// verify params and log errors found
if (games == null)
return console.log("An error occured while trying to log games scores");
if (teams.length < 2)
return console.log("An error occured while trying to log games scores");
try {
// filter the results to just the game or games representing the teams
// we want from the returned results
let game = games.filter((el) => {
return (
// Check for the game that matches both teams. You are likely able
// to match by only one team name but just in case
// Check for the teams name in the visiting team section
(el.vTeam.nickName.toLowerCase() == teams[0].toLowerCase()
|| el.vTeam.nickName.toLowerCase() == teams[1].toLowerCase())
// Check for the teams name in the home teams section
&& (el.hTeam.nickName.toLowerCase() == teams[0].toLowerCase()
|| el.hTeam.nickName.toLowerCase() == teams[1].toLowerCase())
);
});
// log the scores for the home team and visiting team to the console
game.forEach((el) => {
console.log(`(Home) ${el.hTeam.nickName}: ${el.hTeam.score.points}`);
console.log(`(Visitor) ${el.vTeam.nickName}: ${el.vTeam.score.points}`);
});
} catch (error) {
console.log({ error, teams, games});
}
}
我重新设置了这个问题的格式以正确显示问题并显示我之前为获得所需结果所做的尝试。
下面是来自 rapid.api 的 NBA API 回复 这个具体的回复 (https://api-nba-v1.p.rapidapi.com/games/live/) 吐出了目前 live/ongoing 的当前 NBA 比赛。
我正在使用此 API 和其他各种回复,以直接的方式检索 NBA 信息。 我的脚本是为 Discord 设计的。
在我拥有的这个 Discord 服务器中,我们为每场 NBA 比赛制作频道,以便用户可以讨论它。我一直在尝试制作一个显示当前游戏分数的分数命令。
我的issue/goal:
我一直在努力寻找一种方法;
- 通过球队的昵称匹配频道名称(游戏频道名称的示例是:lakers-vs-nets),这将让我确保我得到正确游戏的分数
- 从主队和客队中检索比分
- 打印主队和客队的比分。
我不熟悉 APIs 并试图更好地使用它们,并且我已经学会了更多创造性的方式来使用 Javascript。因此,我们将不胜感激对此问题的任何帮助和解释;谢谢。
"api":{
"status":200
"message":"GET games/live"
"results":4
"filters":[
0:"seasonYear"
1:"league"
2:"gameId"
3:"teamId"
4:"date"
5:"live"
]
"games": [
0: {
"seasonYear":"2021"
"league":"standard"
"gameId":"10187"
"startTimeUTC":"2022-01-13T00:30:00.000Z"
"endTimeUTC":""
"arena":"Madison Square Garden"
"city":"New York"
"country":"USA"
"clock":"1:35"
"gameDuration":"2:05"
"currentPeriod":"4/4"
"halftime":"0"
"EndOfPeriod":"0"
"seasonStage":"2"
"statusShortGame":"2"
"statusGame":"In Play"
"vTeam":{
"teamId":"8"
"shortName":"DAL"
"fullName":"Dallas Mavericks"
"nickName":"Mavericks"
"logo":"https://upload.wikimedia.org/wikipedia/fr/thumb/b/b8/Mavericks_de_Dallas_logo.svg/150px-Mavericks_de_Dallas_logo.svg.png"
"score": {
"points":"82"
}
}
"hTeam":{
"teamId":"24"
"shortName":"NYK"
"fullName":"New York Knicks"
"nickName":"Knicks"
"logo":"https://upload.wikimedia.org/wikipedia/fr/d/dc/NY_Knicks_Logo_2011.png"
"score":{
"points":"121"
}
}
1: {
"seasonYear":"2021"
"league":"standard"
"gameId":"10189"
"startTimeUTC":"2022-01-13T02:00:00.000Z"
"endTimeUTC":""
"arena":"Vivint Arena"
"city":"Salt Lake City"
"country":"USA"
"clock":"8:08"
"gameDuration":"1:46"
"currentPeriod":"4/4"
"halftime":"0"
"EndOfPeriod":"0"
"seasonStage":"2"
"statusShortGame":"2"
"statusGame":"In Play"
"vTeam":{...}
"hTeam":{...}
]
}
}
vTeam 和 hTeam 在这里折叠以压缩代码,但它应该让您了解响应,因为它与之前的几乎相同,只是不同的团队、分数等。
这是我到目前为止尝试过的一些代码:
function iterationObject(obj) {
for(prop in obj) {
// If Object
if (typeof(obj[prop]) == "object"){
// Push
iterationObject(obj[prop]);
} else {
/* This only seems to work if I run solely search for the keys and not the values. So for example, this would work:
if (prop == "nickName" || prop == "shortName"){
console.log(prop + ': ', obj[prop])
}
^ This would work and print the values from anything matching nickName and shortName keys (so in this case, it would print every nickName and shortName it found.*/
if (prop == "nickName" && obj[prop] == "Knicks"){
console.log(prop + ': ', obj[prop])
// ^ This is the last thing that I have tried, but has been returning undefined.
}
}
}
}
case 'gamescore':
var gamescoreurl = "https://api-nba-v1.p.rapidapi.com/games/live/";
axios.get(gamescoreurl, {
headers: {
"x-rapidapi-key": apikey,
"x-rapidapi-host": apihost
}
}).then(response=> {
/* Something I tried with .find, only seems to search surface level with the response. What I mean by that is,
I can dive into games API response, but I can't go games.hTeam with .find
var firstchannelpart = message.channel.name
var gamechannelfinder = firstchannelpart.split("-")[0];
var gameapiresp= response.data.api.games
const hscore = gameapiresp.find(el => {
return el.nickName== gamechannelfinder
})
console.log(hscore)
*/
// My latest attempt, which works retrieving specific values that match using prop as a var in iterationObject. Also, the item variable returns as undefined here, but iterationObject will print from the console what it is supposed to.
tidobj.filter(item => {
iterationObject(item)
})})
break;
你可以看到我发表了一些评论,这些评论仅供本帖帮助理解我之前的尝试,但我觉得其中一个可能就在正确的边缘。
根据上面列出的 API 结果,您可以做类似的事情,
// Set up our sample vars
let channelName = "Mavericks-vs-Knicks";
let gamescoreurl = "https://api-nba-v1.p.rapidapi.com/games/live/";
// Make Axios Call
axios.get(gamescoreurl, {
headers: {
"x-rapidapi-key": apikey,
"x-rapidapi-host": apihost
}
}).then(results => {
// get array of team names to pass to 'LogGameScores'
let teamNickNames = GetTeamsFromChannelName(channelName);
// Log the game scores
LogGameScores(teamNickNames, results?.games);
})
这是一个从频道名称中获取团队名称的简单函数。
function GetTeamsFromChannelName(name = "channelName") {
return name.split("-vs-"); // Split the team Nick Names from the channel name
}
以及获取/记录分数的方法
function LogGameScores(teams = [], games = null) {
// verify params and log errors found
if (games == null)
return console.log("An error occured while trying to log games scores");
if (teams.length < 2)
return console.log("An error occured while trying to log games scores");
try {
// filter the results to just the game or games representing the teams
// we want from the returned results
let game = games.filter((el) => {
return (
// Check for the game that matches both teams. You are likely able
// to match by only one team name but just in case
// Check for the teams name in the visiting team section
(el.vTeam.nickName.toLowerCase() == teams[0].toLowerCase()
|| el.vTeam.nickName.toLowerCase() == teams[1].toLowerCase())
// Check for the teams name in the home teams section
&& (el.hTeam.nickName.toLowerCase() == teams[0].toLowerCase()
|| el.hTeam.nickName.toLowerCase() == teams[1].toLowerCase())
);
});
// log the scores for the home team and visiting team to the console
game.forEach((el) => {
console.log(`(Home) ${el.hTeam.nickName}: ${el.hTeam.score.points}`);
console.log(`(Visitor) ${el.vTeam.nickName}: ${el.vTeam.score.points}`);
});
} catch (error) {
console.log({ error, teams, games});
}
}