【问题标题】:Remove if statements删除 if 语句
【发布时间】:2020-03-18 23:27:52
【问题描述】:

我正在为 Discord 制作一个机器人。要在用户键入命令时加载命令,我需要验证命令是否存在,但现在我有三倍几乎相同的 if 语句。有没有办法只用一个表达式来获取所有内容?

    if (!client.commands[cat]) return;

    if (client.commands[cat][command]) {

        if (client.commands[cat][command].conf) {
            if (client.elevationManager.calculateGuildElevation(message.author.id, message.guild) < client.commands[cat][command].conf.elevation) return message.reply(`you don't have the required elevation to use this command.`);
            if (client.commands[cat][command].conf.accountRequired)
                if (!(await client.accountsManager.findById(message.author.id))) return message.reply(`you must have an account to use this command ! Type \`,,account create\` to get one.`);
            return client.commands[cat][command].run(client, args, message);

        } else if (!args[0]) {
            if (client.elevationManager.calculateGuildElevation(message.author.id, message.guild) < client.commands[cat][command].conf.elevation) return message.reply(`you don't have the required elevation to use this command.`);
            if (client.commands[cat][command].conf.accountRequired)
                if (!(await client.accountsManager.findById(message.author.id))) return message.reply(`you must have an account to use this command ! Type \`,,account create\` to get one.`);
            return client.commands[cat][command].run(client, args, message);

        } else if (!client.commands[cat][args[0]]) {
            if (client.elevationManager.calculateGuildElevation(message.author.id, message.guild) < client.commands[cat][command].conf.elevation) return message.reply(`you don't have the required elevation to use this command.`);
            if (client.commands[cat][command].conf.accountRequired)
                if (!(await client.accountsManager.findById(message.author.id))) return message.reply(`you must have an account to use this command ! Type \`,,account create\` to get one.`);
            return client.commands[cat][command].run(client, args, message);

        } else { ...

【问题讨论】:

  • 顺便说一句,第二个 if 没有必要,因为第一个返回另一个状态
  • 哦,没错,你

标签: javascript node.js discord.js


【解决方案1】:

只需使用||(or) 运算符

    if (!client.commands[cat]) return;

    if (client.commands[cat][command]) {

        if (client.commands[cat][command].conf || !args[0] || !client.commands[cat][args[0]]) {
            if (client.elevationManager.calculateGuildElevation(message.author.id, message.guild) < client.commands[cat][command].conf.elevation) return message.reply(`you don't have the required elevation to use this command.`);
            if (client.commands[cat][command].conf.accountRequired)
                if (!(await client.accountsManager.findById(message.author.id))) return message.reply(`you must have an account to use this command ! Type \`,,account create\` to get one.`);
            return client.commands[cat][command].run(client, args, message);

        } else { ...

@VLAZ 对此有一个更好的答案,显示了更好的编程实践,去看看他的解决方案。

【讨论】:

  • 这是完美的 ty
【解决方案2】:

让我更抽象地表示一下代码的样子:

if (mainCondition1) {
  if (subCondition1) return result1;
  if (subCondition2)
    if (subCondition3) return result2;
   return result3;
} else if (mainCondition2) {  
  if (subCondition1) return result1;
  if (subCondition2)
    if (subCondition3) return result2;
   return result3;
} else if (mainCondition3) {
  if (subCondition1) return result1;
  if (subCondition2)
    if (subCondition3) return result2;
   return result3;
}

这使得推理代码更容易。也更容易看到重复的确切位置,它是

if (subCondition1) return result1;
if (subCondition2)
  if (subCondition3) return result2;
return result3;

在不同条件下出现 3 次。


首先

if (A) { 
  if (B) { 
   doSomething() 
  } 
}

表现相同(并且可以简化为):

if (A && B) { 
 doSomething() 
}

因为里面的代码只有在条件A和条件B都为真时才会执行。这是第一步,重复的部分可以缩短为:

if (subCondition1) return result1;
if (subCondition2 && subCondition3) return result2;
return result3;

接下来是构造:

if (A) {
  doSomething()
} else if (B) {
  doSomething()
}

也可以表示为简单的布尔代数:

if (A || B) {
  doSomething()
}

因为如果至少有一个条件正确,内部代码将被执行。

把这条规则落实到位,三个重复的部分(在三种不同的条件下)折叠成一个块:

if (mainCondition1 || mainCondition2 || mainCondition3) {
  if (subCondition1) return result1;
  if (subCondition2 && subCondition3) return result2;
  return result3;
}

现在只需提取逻辑,您还可以简化完整的表达式:

//extract into variables - no evaluation overhead
const mainCondition1 = client.commands[cat][command].conf;
const mainCondition2 = !args[0];
const mainCondition3 = !client.commands[cat][args[0]];

//extract into functions - only evaluate if needed
const subCondition1 = () => client.elevationManager.calculateGuildElevation(message.author.id, message.guild) < client.commands[cat][command].conf.elevation;
const subCondition2 = () => client.commands[cat][command].conf.accountRequired;
const subCondition3 = async () => !(await client.accountsManager.findById(message.author.id));

if (mainCondition1 || mainCondition2 || mainCondition3) {
  if (subCondition1()) 
    return message.reply(`you don't have the required elevation to use this command.`);
  if (subCondition2() && await subCondition3()) 
    return message.reply(`you must have an account to use this command ! Type \`,,account create\` to get one.`);
  return client.commands[cat][command].run(client, args, message);
}

随意为变量和函数附加更有意义的名称。它们应该真正反映内容是什么,并使您的代码自我记录。由于我实际上并不知道每个背后的意图是什么,因此我的猜测可以作为示例:

const hasConfiguration = client.commands[cat][command].conf;
const noArgumentSupplied = !args[0];
const commandDoesNotSupportArgument = !client.commands[cat][args[0]];

const authorHasInsufficientElevation = () => client.elevationManager.calculateGuildElevation(message.author.id, message.guild) < client.commands[cat][command].conf.elevation;
const accountRequiredForCommand = () => client.commands[cat][command].conf.accountRequired;
const accountDoesNotExist = async () => !(await client.accountsManager.findById(message.author.id));

if (hasConfiguration || noArgumentSupplied || commandDoesNotSupportArgument ) {
  if (authorHasInsufficientElevation()) 
    return message.reply(`you don't have the required elevation to use this command.`);
  if (accountRequiredForCommand() && await accountDoesNotExist()) 
    return message.reply(`you must have an account to use this command ! Type \`,,account create\` to get one.`);
  return client.commands[cat][command].run(client, args, message);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 2014-05-21
    • 1970-01-01
    • 2018-12-06
    相关资源
    最近更新 更多