使用异或简化逻辑判断
认识异或
我们平时比较常用 且 &&
, 或 ||
, 非 !
, 你可听说过 异或 ^
?
true ^ true // false
true ^ false // true
false ^ true // true
false ^ false // false
1
2
3
4
2
3
4
简单来讲, 就是相同为 false, 不同为 true, 就是异或.
反过来, 相同为 true, 不同为 false, 就是同或, 只不过异或再取非就可以拿到同或, 所以我们就不需要同或再专门占用一个计算符号了.
现在你认识异或了, 也可能之前就认识了, 那么, 你会用异或吗? 或者说, 哪里可以用到异或呢?
实战练习 1
有个用户信息库, 可以存储用户字段 `姓名 name` 和字段 `手机号 phone`
现在我们需要一个方法来校验用户信息是否存储合理, 通过参数来标记字段是否应该存在
如果应该存在的没有存在, 或者不应该存在的存在了, 即为不合理, 反之, 就是合理
`isInfoSafe(name, phone)`
已知方法 `has(字段名)` 来判断当前字段是否存在, 如 `has('name')`
1
2
3
4
5
6
7
2
3
4
5
6
7
一般来说, 我们可以通过 if / else
表达式很容易实现
function isInfoSafe(name, phone) {
if (name && phone) {
return has('name') && has('phone')
} else if (name) {
return has('name') && !has('phone')
} else if (phone) {
return has('phone') && !has('phone')
} else {
return !has('phone') && !has('phone')
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
那么你想过通过异或来实现吗
function isInfoSafe(name, phone) {
return !(name ^ has('name')) && !(phone ^ has('phone'))
}
1
2
3
2
3
能感受到异或的魅力吗
实战练习 2
当然, 有时候通过异或不总是那么容易, 并且我们也不能够直观的感受到是否容易, 是否适合使用异或
有个用户信息库, 可以存储用户姓名 `字段 name` 和手机号 `字段 phone`
现在我们需要一个方法来判断用户必要的信息是否存在, 通过参数来标记字段是否为必要的信息
`isInfoFull(name, phone)`
已知方法 `has(字段名)` 来判断当前字段是否存在, 如 `has('name')`
如果没有信息字段为必要的, 直接返回 true
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
一般来说, 我们可以通过 if / else
表达式很容易实现
function isInfoFull(name, phone) {
if (name && phone) {
return has('name') && has('phone')
} else if (name) {
return has('name') // <---
} else if (phone) {
return has('phone') // <---
} else {
return true; // <---
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
现在怎么通过异或来实现呢?
function isInfoFull(name, phone) {
return (!(name ^ false) || !(name ^ has('name'))) &&
(!(phone ^ false) || !(phone ^ has('phone')));
}
1
2
3
4
2
3
4
实战练习 3
如果实战练习 2 中, 多了一个字段 年龄 age
, 你能想象 if / else
会变得多复杂吗
function isInfoFull(name, phone, age) {
if (name && phone && age) {
return has('name') && has('phone') && has('age') // <---
} else if (name && phone) {
return has('name') && has('phone') // <---
} else if (name && age) {
return has('name') && has('age') // <---
} else if (phone && age) {
return has('phone') && has('age') // <---
} else if (name) {
return has('name')
} else if (phone) {
return has('phone')
} else if (age) {
return has('age') // <---
} else {
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
但是异或却很轻松
function isInfoFull(name, phone, age) {
return (!(name ^ false) || !(name ^ has('name'))) &&
(!(phone ^ false) || !(phone ^ has('phone'))) &&
(!(age ^ false) || !(age ^ has('age')));
}
1
2
3
4
5
2
3
4
5
总结
我们不是在纠结使用异或 运算符
还是使用 if / else
逻辑表达式,
而是提供了一个全新的思路, 让你的多维度判断抽离出来
function resultByCondition(condition, result) {
return (!(condition ^ false) || !(condition ^ result()))
}
function isInfoFull(name, phone, age) {
return resultByCondition(name, () => has('name')) &&
resultByCondition(phone, () => has('phone'))
resultByCondition(age, () => has('age'));
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
现在, 你的 resultByCondition
方法, 也可以用 if / else
逻辑表达式实现
然而 isInfoFull()
已经可以轻松实现扩展了