我正在为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 { ...
答案 0 :(得分: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
都为true时,内部代码仅执行 。这是第一步,重复的部分可以缩短为:
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);
}
答案 1 :(得分:0)
只需使用||
(或)运算符
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对此有更好的回答,可以显示更好的编程实践,请查看他的解决方案。