如何优化if多层判断

``````aa(item) {
let color;
let eq1 = "";
let eq2 = "";

for (let i = 0; i < this.option.columnTow.length; i++) {
let element = this.option.columnTow[i];
console.log(parseInt(eq1) < parseInt(item.value))
if (eq1 != "" && eq2 != "" && parseFloat(eq1) < parseFloat(item.value) && parseFloat(item.value) < parseFloat(eq2)) {
color = element.prop;
break;
}
else if (eq1 != "" && eq2 != "" && parseFloat(eq2) < parseFloat(eq1)) {
if (element.equation == "大于" && parseFloat(item.value) > parseFloat(element.value)) {
color = element.prop;
break;
}
else if (element.equation == "小于" && parseFloat(item.value) < parseFloat(element.value)) {
color = element.prop;
break;
}
}
if (element.equation == "大于" && eq2 == "" && parseFloat(item.value) > parseFloat(element.value)) {
color = element.prop;
break;
}
if (element.equation == "小于" && eq1 == "" && parseFloat(item.value) < parseFloat(element.value)) {
color = element.prop;
break;
}
if (element.equation == "等于" && parseFloat(item.value) == parseFloat(element.value)) {
color = element.prop;
break;
}
}
return color;
}``````

5 个回答
✓ 已被采纳
1. `function aa``function` 没写，我复制到IDE报错了。
2. 整体看下来逻辑不复杂，循环中判断条并修改color，打断循环，返回color

``````function aa(item) {
let color;
let eq1 = "";
let eq2 = "";

for (let i = 0; i < this.option.columnTow.length; i++) {
let element = this.option.columnTow[i];
console.log(parseInt(eq1) < parseInt(item.value))
if (条件1) { color = element.prop; break; }
else if (条件2) {
if (条件3) { color = element.prop;  break; }
else if (条件4) { color = element.prop; break; }
}
if (条件5) { color = element.prop; break; }
if (条件6) { color = element.prop; break; }
if (条件7) { color = element.prop; break; }
}
return color;
}``````

那实际上并不需要打断这个动作，直接返回值即可，也就是这段可以简化为

``````function aa(item) {
let eq1 = "";
let eq2 = "";

for (let i = 0; i < this.option.columnTow.length; i++) {
let element = this.option.columnTow[i];
console.log(parseInt(eq1) < parseInt(item.value))
if (条件1) return element.prop;
if (条件2 && 条件3) return element.prop;
if (条件2 && 条件4) return element.prop;
if (条件5) return element.prop;
if (条件6) return element.prop;
if (条件7) return element.prop;
}
}``````
3. 条件具备相似性,可以合并同类项。

`````` let 条件1 = eq1 != "" && eq2 != "" && parseFloat(eq1) < parseFloat(item.value) && parseFloat(item.value) < parseFloat(eq2)
let 条件2 = eq1 != "" && eq2 != "" && parseFloat(eq2) < parseFloat(eq1)
let 条件3 = element.equation == "大于" && parseFloat(item.value) > parseFloat(element.value)
let 条件4 = element.equation == "小于" && parseFloat(item.value) < parseFloat(element.value)
let 条件5 = element.equation == "大于" && eq2 == "" && parseFloat(item.value) > parseFloat(element.value)
let 条件6 = element.equation == "小于" && eq1 == "" && parseFloat(item.value) < parseFloat(element.value)
let 条件7 = element.equation == "等于" && parseFloat(item.value) == parseFloat(element.value)``````

一个是判断eq1和eq2，另一个是item.value 和 element.value，这部分简化下来就是

``````
let 条件10 = eq1 == ""
let 条件11 = eq2 == ""
let 条件12 = parseFloat(item.value) - parseFloat(element.value)
let 条件13 = parseFloat(eq2) < parseFloat(eq1)
let 条件14 = element.equation

let 条件1 = !条件10 && !条件11 && !条件13 && parseFloat(eq1) < parseFloat(item.value) && parseFloat(item.value) < parseFloat(eq2)
let 条件3 = !条件10 && !条件11 && 条件13 && 条件14 == "大于" && 条件12 >0
let 条件4 = !条件10 && !条件11 && 条件13 && 条件14 == "小于" && 条件12 <0
let 条件5 = 条件14 == "大于" && 条件11 && 条件12 > 0
let 条件6 = 条件14 == "小于" && 条件10 && 条件12 < 0
let 条件7 = 条件14 == "等于" && 条件12 == 0``````

并且可以看出条件1到条件7是互异的，也就是其中一个成立，其他的肯定都是不成立的。所以顺序并不影响判断，我们调整顺序并用或链接起来

``````function aa(item) {
let eq1 = "";
let eq2 = "";

for (let i = 0; i < this.option.columnTow.length; i++) {
let element = this.option.columnTow[i];
let 条件10 = eq1 == ""
let 条件11 = eq2 == ""
let 条件12 = parseFloat(item.value) - parseFloat(element.value)
let 条件13 = parseFloat(eq2) < parseFloat(eq1)
let 条件14 = element.equation
if (
条件14 == "等于" && 条件12 == 0 ||
条件10 ? (
条件14 == "小于" && 条件12 < 0
) : (
条件11 ? (
条件14 == "大于" && 条件12 > 0
) : (
条件13 ? (
条件14 == "大于" && 条件12 > 0
|| 条件14 == "小于" && 条件12 < 0
) : (
parseFloat(eq1) < parseFloat(item.value) && parseFloat(item.value) < parseFloat(eq2)
)
)
)
) return element.prop;
}
return null
}``````

如果能将`条件14 == "大于" && 条件12 > 0` 封装起来，会更加利于简化。

扁平化

``````    if (eq1 !="" && eq2 !="" &&   parseFloat(eq1) < parseFloat(item.value) && parseFloat(item.value)  < parseFloat(eq2) ){
color= element.prop;
break;
}
else if``````

``````if (xxx) {
color = element.prop;
break;
}
// 后面的计算
if (ooo) {

}
...``````

具体化

``````const isMeathillGoodLookAndKindHearted = meathill
&& meathill.isGoodLook()
&& meathill.isKindHearted();
if (isMeathillGoodLookAndKindHearted) {
giveMoneyTo(meathill);
}``````

``````aa(item) {
let color;
let eq1 = "";
let eq2 = "";

for (let i = 0; i < this.option.columnTow.length; i++) {
let element = this.option.columnTow[i];
console.log(parseInt(eq1) < parseInt(item.value))
// 逻辑1：如果 eq1 和 eq2 都有指定，判断 item.value 是否在它们之间
if (eq1 != "" && eq2 != "" && parseFloat(eq1) < parseFloat(item.value) && parseFloat(item.value) < parseFloat(eq2)) {
color = element.prop;
break;
}
// 逻辑2：如果 eq1 和 eq2 都有值，但无效（假设 eq1 <= eq2 为有效），
// 直接按 element.equation 判断 item.value 和 element.value 的大小
else if (eq1 != "" && eq2 != "" && parseFloat(eq2) < parseFloat(eq1)) {
if (element.equation == "大于" && parseFloat(item.value) > parseFloat(element.value)) {
color = element.prop;
break;
}
else if (element.equation == "小于" && parseFloat(item.value) < parseFloat(element.value)) {
color = element.prop;
break;
}
}

// 剩下的逻辑，① eq1 和 eq2 都有值，且有效；② eq1 和 eq2 不都有值

// 逻辑3：若没有 eq2，即没有最大值，item.value > element.value 算，前提是 equation
if (element.equation == "大于" && eq2 == "" && parseFloat(item.value) > parseFloat(element.value)) {
color = element.prop;
break;
}

// 逻辑4：若没有 eq1，即没有最小值，item.value < element.value 算，前提是 equation
if (element.equation == "小于" && eq1 == "" && parseFloat(item.value) < parseFloat(element.value)) {
color = element.prop;
break;
}

// 逻辑5：若 euqation 是等于，判断 item.value 和 element.value 相等
if (element.equation == "等于" && parseFloat(item.value) == parseFloat(element.value)) {
color = element.prop;
break;
}
}
return color;
}``````

1. 判断 item 和 element 大小关系的时候，都跟 equation 有关，这里可以写一个函数

``````function predicate(item, element, ...types) {
// 如果 element.equalltion 不在指定要进行的比较类型中，直接失败
if (!types.includes(element.equaltion)) {
return false;
}

const [iValue, eValue] =  [item.value, element.value].map(s => parseFloat(s));
switch (element.equaltion) {
case "大于": return iValue > eValue;
case "小于": return iValue < eValue;
case "等于": return iValue === eValue;
default: return false;
}
}``````
2. 可以把 eq1 和 eq2 看成 min 和 max，意义更明确
3. \( min < item < max \) 的时候，跟 element.value 没有关系，只需要取第 1 个 element 的 prop
4. \( max < min \) 的时候，只判断 item 和 element 的大/小关系，不判等
5. 没有 max 的时候，判大于
6. 没有 min 的时候，判小于
7. 其他情况，判等于

``````aa() {
const [minValue, maxValue, itemValue] = [eq1, eq2, item.value].map(s => parseFloat(s));

function predicate(element, ...types) {
if (!types.includes(element.equaltion)) {
return false;
}

const eValue = parseFloat(element.value);
switch (element.equaltion) {
case "大于": return itemValue > eValue;
case "小于": return itemValue < eValue;
case "等于": return itemValue === eValue;
default: return false;
}
}

// 判断某个 element 是否符合条件
function isValidElement(element) {
if (eq1 !== "" && eq2 !== "") {
if (itemValue > minValue && itemValue < maxValue) {
return true;
}
if (maxValue < minValue && predicate(element, "大于", "小于")) {
return true;
}
}

if (eq2 === "" && predicate(element, "大于")) {
return true;
}
if (eq1 === "" && predicate(element, "小于")) {
return true;
}

return predicate(element, "等于");
}

// 对 this.option.columnTow 进行判断，找到符合条件的 element
const element = this.option.columnTow.find(isValidElement);

// 最后还是有可能没找到，会返回 undefined
return  element?.prop;
}``````

``````let color;
let eq1 = "";
let eq2 = "";

for (let i = 0; i < this.option.columnTow.length; i++) {
let element = this.option.columnTow[i];
let eq1Num = parseFloat(eq1);
let eq2Num = parseFloat(eq2);
let itemValNum = parseFloat(item.value);
let eleValNum = parseFloat(element.value);
if (
(eq1 && eq2 && eq1Num < itemValNum && itemValNum < eq2Num) ||
(eq1 &&
eq2 &&
eq2Num < eq1Num &&
((element.equation == "大于" && itemValNum > eleValNum) ||
(element.equation == "小于" && itemValNum < eleValNum))) ||
(element.equation == "大于" && eq2 && itemValNum > eleValNum) ||
(element.equation == "小于" && eq1 && itemValNum < eleValNum) ||
(element.equation == "等于" && itemValNum == eleValNum)
) {
color = element.prop;
break;
}
}
return color;``````

你尚未登录，登录后可以
• 和开发者交流问题的细节
• 关注并接收问题和回答的更新提醒
• 参与内容的编辑和改进，让解决方法与时俱进