繁体   English   中英

Steam API,不同的json格式

[英]Steam API, different json format

最近,我在我的Discord机器人中集成了CSGO统计信息,但是今天我看到,几乎对于每个播放器,API都会发送不同的json数据。

这里有两个例子:

https://jsonblob.com/58688d30-26d0-11e8-b426-7b3214778399 https://jsonblob.com/52ed0c3f-26d0-11e8-b426-43058df4a5a6

我的问题是如何正确地请求数据,因此胜利实际上是胜利而不是杀戮。

  .addField('**Wins:**', `${object.playerstats.stats[5].value}`, true) .addField('**Time played:**', `${object.playerstats.stats[2].value}` + ' minutes', true) .addField('**Kills:**', `${object.playerstats.stats[0].value}`, true) .addField('**Deaths:**', `${object.playerstats.stats[1].value}`, true) .addField('**Bombs planted:**',`${object.playerstats.stats[3].value}`, true) .addField('**Money earned:**',`${object.playerstats.stats[7].value}`, true) .addField('**Knife kills:**',`${object.playerstats.stats[9].value}`, true) .addField('**Headshot kills:**',`${object.playerstats.stats[24].value}`, true) .addField('**Dominations:**',`${object.playerstats.stats[39].value}`, true) .addField('**Rounds played:**',`${object.playerstats.stats[44].value}`, true) 

统计项目的name属性看起来足够独特。 您可以使用array.find按名称查找正确的统计信息。

const stats = object.playerstats.stats
const totalKills = stats.find(s => s.name === 'total_kills').value
const totalDeaths = stats.find(s => s.name === 'total_deaths').value

更进一步,您可以使用array.reduce生成一个对象,该对象的键是name ,值是数组中每个项目的value 这样,您可以像访问对象一样访问它。

const stats = object.playerstats.stats
const statsObj = stats.reduce((c, e) => (c[e.name] = e.value, c), {})

const totalKills = statsObj.total_kills
const totalDeaths = statsObj.total_deaths

与其尝试引用数组索引,不如不将API响应转换为易于解析的格式?

// do this once...
let playerStats = {};
object.playerstats.stats.forEach(s => playerStats[s.name] = s.value);

// ...then you can use the playerStats variable however you need:
.addField('**Kills:**', `${playerStats.total_kills}`, true)
.addField('**Wins:**', `${playerStats.total_wins}`, true)

stats数组只是未排序。 您可以使用.find()从统计信息中获取正确的条目。

例如

const totalWins = object.playerstats.stats.find(stat => {
    return stat.name === 'total_wins';
});
.addField('**Wins:**', `${totalWins.value}`, true)

您正在以错误的方式解决此问题。

JSON不是一种有序的格式。 这意味着不能保证JSON数据每次都会以相同的顺序返回。 这不是API的默认设置。

您仍然可以使用一种方法:按名称对“ stats”数组进行排序。 但这是一个漫长的过程,不是一个好主意。

这样做的方法是按名称进行查找。 例如,如果您想找到胜利,可以这样做:

object.playerstats.stats.find(elem => elem.name === 'total_wins').value;

find函数执行查找并返回与谓词匹配的第一个元素(elem.name ==='total_wins')。 如果元素不匹配谓词,则返回null(因此请注意此处)。

您可以执行一个为您返回值的函数:

findValue(statsArray, name) {
    const entry = statsArray.find(elem => elem.name === name);
    return entry ? entry.value : '?';
}

然后您的代码将如下所示:

 ...
 .addField('**Wins:**', findValue(object.playerstats.stats, 'total_wins'), true)
 ...

这里的主要内容是: 永远不要假设JSON中的字段每次都会返回相同的字段。 始终使用查找,而不使用索引(除非已排序)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM