Javascript 开关内的索引
我有一个用于Xat聊天室的基于Javascript的机器人,它也可以作为AI。我最近决定重做它的AI部分,因为它变成了一个绝对庞大的Javascript 开关内的索引,javascript,switch-statement,tampermonkey,Javascript,Switch Statement,Tampermonkey,我有一个用于Xat聊天室的基于Javascript的机器人,它也可以作为AI。我最近决定重做它的AI部分,因为它变成了一个绝对庞大的else if语句链,几乎无法使用 我做了一些研究,提出了一个如何处理回应的新想法。我将首先向您提供代码段: function msgSwitch(id,msgRes) { var botResponse = []; switch (msgRes) { case (msgRes.indexOf("hi") !=-1): botResponse.push
else if
语句链,几乎无法使用
我做了一些研究,提出了一个如何处理回应的新想法。我将首先向您提供代码段:
function msgSwitch(id,msgRes) {
var botResponse = [];
switch (msgRes) {
case (msgRes.indexOf("hi") !=-1):
botResponse.push("HELLO. ");
case (msgRes.indexOf("how are you") !=-1):
botResponse.push("I AM FINE. ")
case (msgRes.indexOf("do you like pie") !=-1):
botResponse.push("I CAN'T EAT. THANKS, ASSHAT. ")
default:
respond (botResponse);
spamCount(id);
break;
}
}
这里的想法是检查msgRes
(用户的输入)并查看它匹配多少个案例。然后,对于每个匹配,它将将响应推送到botResponse
数组中,最后,它将使用该数组中的所有消息进行回复
示例
用户消息:Hi!你好吗?
msgRes:你好
机器人匹配:
hi
>将HELLO.
推送到数组
你好吗
>推我很好。
到array
机器人响应:你好。我很好。
这反过来又省去了为每个可能的组合编写if
的麻烦
但是,在进一步研究之后,我不确定是否可以在交换机内部使用indexOf
。有没有人知道解决这个问题的方法,或者有没有更好的办法以同样的方式处理回复
编辑:
避免XY问题(澄清我的问题)
我需要一个干净的替代方案来代替使用大量的else if
语句。机器人将响应数百个字段。如果它不能继续搜索匹配项,我就必须为每个组合编写一个新的else,如果
我希望能找到一种方法,让它扫描每一条语句中的一个匹配项,然后将每个匹配项的响应组合成一个字符串
编辑2:
我还应该补充一点,这是在Tampermonkey上运行的,而不是一个网站。我的两分钱作为您尝试做的要点:
function msgSwitch(id, msgRes) {
var seed = {'hi': 'HELLO. ', 'how are you': 'I AM FINE'};
var botResponse = [];
for (var key in seed) {
if (msgRes.indexOf(key) !== -1) {
botResponse.push(seed[key]);
}
}
}
在我看来,更改此程序更容易,因为如果将来有更多响应,您只需编辑种子。您甚至可以将种子保存在某个json文件中并读取它(通过ajax),这样,如果有其他消息,程序就不需要更改。您只需要将其与true进行比较,而不是与msgRes进行比较(因为案例使用===比较),并使用break来防止令人讨厌的切换行为:
function msgSwitch(id,msgRes) {
var botResponse = [];
switch (true) {
case (msgRes.indexOf("hi") !=-1):
botResponse.push("HELLO. "); break;
case (msgRes.indexOf("how are you") !=-1):
botResponse.push("I AM FINE. "); break;
case (msgRes.indexOf("do you like pie") !=-1):
botResponse.push("I CAN'T EAT. THANKS, ASSHAT. "); break;
default:
respond (botResponse);
spamCount(id);
break;
}
}
这是一种完全有效的逻辑分叉模式,称为“重载开关”。很多人可能没有意识到每一个案例:
都是一个表达式,而不仅仅是一个值,所以如果需要,你甚至可以在其中加入一个生命…这是完全不可能的。如果
,请使用else。您可能需要再次阅读开关
的工作原理。该函数中甚至没有使用参数id
,您可以将其删除!下一个答案很好地解决了这个问题-这个答案(虽然有效)实际上并没有解释为什么switch()不起作用,并且对其他与OP类似问题的人没有帮助。@Levidps这个答案来自2014=),虽然我已经从这样的命令式编程开始了,但我想为我的答案辩护。OP说他想避免很多if/else/elseif连接,我想到了这一点——优点是代码行更短,种子可以从程序中移除,并通过其他方式读取。能够独立于程序更改种子是配置的宗旨,并促进关注点的分离。正如我所说的,如果种子来自后端程序(REST服务),那么只有在有新的种子时后端才需要更改messages@ailveen错过了关于避免if/else的部分。我看到了使用for循环的有效性,但是我在类似的上下文中遇到了这一点,并且需要保持switch语句的使用。所以第二个答案对我的需求更有用。非常有用的答案,尤其是“真实”部分。将case表达式封装在括号中有什么特别的原因吗?@DanielBöttner:为了尽可能地保留OP的代码,不需要它们。100%这应该是答案。选择的答案是一个有效的解决方案,但实际上没有解释开关()不工作的原因。这正确地回答了问题,修复了代码,并为那些有类似问题的人提供了清晰的细节。