简体   繁体   English

Steam API,不同的json格式

[英]Steam API, different json format

Recently i integrated CSGO stats in my discord bot, but today i saw that for almost every player the API sends a different json data. 最近,我在我的Discord机器人中集成了CSGO统计信息,但是今天我看到,几乎对于每个播放器,API都会发送不同的json数据。

Here 2 examples: 这里有两个例子:

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

My question was how to request the data properly so a win is really a win and not a kill. 我的问题是如何正确地请求数据,因此胜利实际上是胜利而不是杀戮。

  .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) 

The name property of stats items appear to be unique enough to find. 统计项目的name属性看起来足够独特。 You can use array.find to look for the correct stat by 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

Taking it further, you can use array.reduce to generate an object whose key is name and value is value for each item in the array. 更进一步,您可以使用array.reduce生成一个对象,该对象的键是name ,值是数组中每个项目的value This way, you access it like an object. 这样,您可以像访问对象一样访问它。

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

Rather than trying to reference the array indexes, why not convert the API response into an easier-to-parse format? 与其尝试引用数组索引,不如不将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)

The stats array is just not sorted. stats数组只是未排序。 you can use .find() to get the correct entry from the stats. 您可以使用.find()从统计信息中获取正确的条目。

for example 例如

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

You are approching this problem the wrong way. 您正在以错误的方式解决此问题。

JSON is not a format that is ordered. JSON不是一种有序的格式。 What that means is that there is no guarantee that the JSON data will return in the same order everytime. 这意味着不能保证JSON数据每次都会以相同的顺序返回。 It is not a default of the API. 这不是API的默认设置。

There is one way you could still use your way: by sorting the 'stats' array by name. 您仍然可以使用一种方法:按名称对“ stats”数组进行排序。 but it is a long operation and not a very good idea. 但这是一个漫长的过程,不是一个好主意。

The way do to this is to do a lookup by name. 这样做的方法是按名称进行查找。 For example, if you want to find the wins, you do this : 例如,如果您想找到胜利,可以这样做:

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

The find function does a lookup and returns the first element matching the predicate (elem.name === 'total_wins'). find函数执行查找并返回与谓词匹配的第一个元素(elem.name ==='total_wins')。 It returns null if not element matched the predicate (so be careful here). 如果元素不匹配谓词,则返回null(因此请注意此处)。

You could do a function that returns a value for you : 您可以执行一个为您返回值的函数:

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

And then your code would look like this : 然后您的代码将如下所示:

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

The main thing here is : never assume fields in a JSON will return the same every time. 这里的主要内容是: 永远不要假设JSON中的字段每次都会返回相同的字段。 Always use lookup, and not indexes (unless it is sorted). 始终使用查找,而不使用索引(除非已排序)。

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

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