节点获取 JSON 问题

Posted

技术标签:

【中文标题】节点获取 JSON 问题【英文标题】:Node-fetch JSON problems 【发布时间】:2021-07-01 09:30:33 【问题描述】:

我目前正在为我的不和谐机器人开发计算器功能。我做了一个获取steam市场物品价格的命令,然后根据公式计算:([price] - [price * 0.15]) * amount of cases,其中0.15是市场费用。这就是问题出现的地方。

程序将json.lowest_price 视为一个词,而不是一个数字(我认为)。结果,bot 发送带有NaN 的消息。我不知道如何让我的代码正确地将 JSON 视为一个数字。

这是我的代码:

const Discord = require('discord.js');
const fetch = require('node-fetch');
const client = new Discord.Client();

client.login('[TOKEN]');

client.on('ready', () => 
  console.log(`Logged in as TEST`);
);

//////////////////////////////////

const prefix = "!";
client.on('message', message =>
  if (!message.content.startsWith(prefix) || message.author.bot) return;
  const args = message.content.slice(prefix.length).trim().split(/ +/);
  const command = args.shift().toLowerCase();

if (command === 'calculate') 
  if (!args.length)
    return message.channel.send(`Invalid argument`);
   else if (args[0] === 'breakout')
    fetch(
    'https://steamcommunity.com/market/priceoverview/?appid=730&market_hash_name=Operation%20Breakout%20Weapon%20Case&currency=6',
  )
    .then((res) => res.json())
    .then((json) =>
      message.channel.send(
        `From $args[1]] breakout cases you will get $((json.lowest_price)-((json.lowest_price)*0.15))*(args[1])`,
      ),
    )
    .catch((error) => 
      console.log(error);
      message.channel.send('tracking breakout price failed');
    );
  

);

【问题讨论】:

【参考方案1】:

响应包含lowest_price 作为字符串(如"7,89zł")。似乎 API 确实在 lowest_price 字段中包含了格式化货币,这就是您在使用它时收到 NaN 的原因。

您可以通过删除货币符号、删除点以及将逗号替换为点来手动将其转换为数字:

function getNumberFromCurrency(currency) 
  return Number(
    currency
    .replace(/[zł.]/g, '')
    .replace(',', '.')
  )


const amount = '10';
const lowestPrice = "7,89zł";
const lowestPriceValue = getNumberFromCurrency(lowestPrice);
const finalPrice = (lowestPriceValue - lowestPriceValue * 0.15) * amount;

console.log( lowestPriceValue, finalPrice );
// => 7.89, 67.065

但我建议您安装 currency.js 软件包,因为它真的很容易使用。它可以从任何货币中获取价值,并且具有内置的乘法、减法等。您需要使用上面提到的公式的一切。查看下面的工作代码:

const currency = require('currency.js');

// ... 
// ...


client.on('message', (message) => 
  if (!message.content.startsWith(prefix) || message.author.bot) return;
  const args = message.content.slice(prefix.length).trim().split(/ +/);
  const command = args.shift().toLowerCase();

  // you can change the format, localising the decimal and/or delimiter
  const zloty = (value) =>
    currency(value,  symbol: 'zł', separator: '.', decimal: ',' );

  if (command === 'calculate') 
    if (!args.length) 
      return message.channel.send(`Invalid argument`);
     else if (args[0] === 'breakout') 
      fetch(
        'https://steamcommunity.com/market/priceoverview/?appid=730&market_hash_name=Operation%20Breakout%20Weapon%20Case&currency=6'
      )
        .then((res) => res.json())
        .then((json) => 
          // calculate the final price using currency.js only
          const finalPrice = zloty(
            zloty(json.lowest_price)
             .subtract(
               zloty(json.lowest_price)
                 .multiply(0.15)
               )
            )
            .multiply(args[1])
            .format();

          message.channel.send(`From $args[1] breakout cases you will get $finalPrice`);
        )
        .catch((error) => 
          console.log(error);
          message.channel.send('tracking breakout price failed');
        );
    
  
);

【讨论】:

以上是关于节点获取 JSON 问题的主要内容,如果未能解决你的问题,请参考以下文章

多个节点同名时使用 Oracle SQL 获取 JSON_VALUE

使用节点 mysql2 获取 JSON 键作为列

NodeJS - 使用节点获取发送 JSON 对象参数

如何使用 JSON 格式获取 Prometheus 节点导出器指标

从json数据中获取父子关系中所有子节点的总和

如何获取json数组的子节点的值