多个嵌套开关语句的最佳替代方案



我有一个JavaScript函数,它有多个嵌套的开关用例,这完全是一团糟。在过去的几个月里,该功能已经扩展,现在我想重组代码。在任何情况下,都应该将不同的值推送到已经存在的变量中

下面是我的代码示例:

switch(var1){
case 1:
switch(var2){
case 0:
switch(var3){
case 'test':
switch(i){
case 0: endresult.push({id: i, content: '123'}); break;
case 2: endresult.push({id: i, content: '124'}); break;
}
break;
default:
endresult.push({id: i, content: '125'}); break;
}
break;
case 1:
endresult.push({id: i, content: '126'}); break;
}
break;
case 2:
switch(var2){
case 0:
switch(i){
case 0: endresult.push({id: i, content: '127'}); break;
case 2: endresult.push({id: i, content: '128'}); break;
}
break;
case 1:
switch(i){
case 0: endresult.push({id: i, content: '128'}); break;
case 2: endresult.push({id: i, content: '129'}); break;
}
break;
}
break;
}

重写这篇文章的最佳方式是什么?

拥有所有可能变化及其值的映射:

// Key is composite of `"" + var1 + "_" + var2 + "_" + i` and trimmed `_` from back
let tree = {
'1_0_test_0': '123',
'1_0_test_2': '124',
'1_0_test': '125',
'1_0_1': '126',
...
}
let key = ("" + var1 + var2 + i).replace(/_{2,}|_+$/, '');
if (typeof tree[key] !== 'undefined') {
endresult.push({id: i, content: tree[key]});
}

您关心的是可读性,对吗?您可能需要对代码进行一点拆分。并使用变量名,而不是0和1。此外,您还需要提供更多详细信息。比如它可以超越0和1到2和3等等。我不确定你是如何调用你的代码的。

然而,您可以尝试(混合对象和其他对象):

const decideFn = ({ var1, var2, var3, i }) = {
const decision = {
1: {
0: {
cond(i) {
if (var3 === 'test') {
if (i === 0) 
endresult.push({id: i, content: '123'})
else if (i === 2) 
endresult.push({id: i, content: '124'})
else 
endresult.push({id: i, content: '125'})
}
else endresult.push({id: i, content: '125'})
}
},
1: {
cond(i) { 
endresult.push({id: i, content: '126'}) 
}
}
}
2: {
0: {
cond(i) {            
if (i === 0) 
endresult.push({id: i, content: '127'})
else if (i === 2) 
endresult.push({id: i, content: '128'})}
},
1: {
cond(i) {
if (i === 0) 
endresult.push({id: i, content: '128'})
else if (i === 2) 
endresult.push({id: i, content: '129'}) 
}
}
}
}
// usage
// does i go in a loop ?
// your qn needs more details. but i hope you get the idea
decision[var1][var2].cond(i)
}

最终,它实际上可以归结为你觉得自己最了解代码,以及其他开发人员会如何阅读你的代码,但我个人认为你的switch语句很好。

不过,对象可能会提供更大的灵活性。

如果在每种情况下你都在推送同一个变量,我会考虑创建一个函数,它的唯一工作是根据变量确定正确的值。

这可能看起来像这样:

const getContentValue(var1, var2, var3, i) {
if (var1 === 1) {
if (var2 === 0) {
if (var3 === 'test') {
if (i === 0) return '123'
if (i === 2) return '124'
return '125'
}
if (var2 === 1) {
return '126'
}
}
if (var1 === 2) {
if (var2 === 0) {
if (i === 0) return '127'
if (i === 2) return '128'
}
if (var2 === 1) {
if (i === 0) return '128'
if (i === 2) return '129'
}
}
}
endResult.push({ id: i, content: getContentValue(var1, var2, var3, i) })

(代码未经测试。)

需要注意的几件事和需要遵循的几条原则:

  • 基本的";决策结构";是相同的,但通过使用if语句进行了简化。在我看来,在案件之间切换是当你有很多案件时你会做的事情,而不是当你在两件事之间切换时。当您在两个选项之间切换时,if语句非常有效。如果你真的在处理一堆案例,比如你的var1实际上可能是10+个不同的数字,那么使用switch可能更简单
  • 如果您查看代码中的switch语句,那么对于每种情况都有很多相同的内容。一个技巧是观察每种情况下答案的变化。CCD_ 5是相同的。只有数字会改变。这是一条简化事物的好路
  • 我不认为这是故意的,但有两种情况会导致数字128。您可能可以做一些额外的简化。(很难确切地知道,因为我知道你所掌握的样本数据并不完全是你正在处理的真实数据。)我之所以发表评论,是因为这实际上是一个很好的教学时刻——如果你有完全相同的最终案例,那就需要好好看一看
  • 注意switch语句和if语句的概念之间的相似性。在函数中,如果您有一个return语句,它的作用将类似于switch语句的break。如果您在每个if案例之后返回,那么当您有足够的信息知道返回内容时,您将获得相当于default案例的信息。(例如,请参阅写着return '125'的行。我们知道,如果我们达到这一点,应该返回125。)

最新更新