问题描述
myArray = [false,false,false]
根据每种状态,我需要做不同的事情。
ex:
[false,true,false],[false,true],[true,...
以此类推。
通常,这种操作是通过检查每个单独的元素是否合适来完成的。
例如:
if(!myArray[0] && myArray[1] && !myArray[2]) do A
if(!myArray[0] && !myArray[1] && myArray[2]) do B
if(myArray[0] && myArray[1] && !myArray[2]) do C
...
而不是那样做。我将数组转换为String:
switch(JSON.stringify(myArray))
case : "[false,false]"
do A
break
case : "[false,true]"
do B
break
case : "[true,false]"
do C
break
......
这被认为是好的做法吗?使用此方法可能会遇到任何隐藏的错误吗? 这种方法会增加可读性吗?
解决方法
它本身没有多大错误,取决于上下文。这些布尔中有多少个,它们来自哪里/是什么原因,有多少种情况,等等。坏的地方可能是很难理解正在发生的事情并进行调试,特别是如果您有10个以上的值在那里。
您也许可以将每个布尔值转换为在该上下文中有意义的字符串/单词,因此您会得到一个句子。如果每个布尔值都有唯一的单词,则可以省略错误的单词,因此只需写下某些组合即可。
也可以使用JSON.stringify()
代替myArray.join(',')
,它输出true,true,false
(因此不带括号)。
您的目标是编写可读的if吗?
Stringify是一种解决方案,但是(也许仅对我而言)有点奇怪。
这是我的建议。编写这样的函数:
isEqual(left,right) {
if (left.length !== right.length) return false;
for (var i = 0; i < left.length; i++) {
if (left[i] !== right[i]) return false;
}
return true;
}
并像这样使用它:
if (isEqual(array,[true,false,true])) alert('isEqual');
,
关于使用JSON.stringify
使用JSON.stringify
可以很好地用于(JSON兼容)原语的(数组(数组))数组,即布尔值,字符串,数字,空值。没有歧义。 ECMAScript规范对于在不同值之间产生的“间隙”也很清楚:除非是通过可选参数明确定义的不同,否则它应该是空字符串。参见ECMAScript Language Specification on the topic。
一个警告是undefined
在JSON中不是问题,因此[null]
和[undefined]
都将被字符串化为“ [null]”。但是,由于您仅使用false
和true
,所以这不是问题。
现在您的问题是
这被认为是好的做法吗?
这是见仁见智。我的第一个直觉说“不”,主要是因为类型转换,但是由于没有针对您的特定用例(即布尔数组)的警告,因此我们实在没有什么可批评的。
使用此方法可能会遇到任何隐藏的错误吗?
否
此方法会增加可读性吗?
是
但是,至少有一种替代方法具有所有相同的优点,但不依赖于某些数据类型转换:
替代:位集
如果您的数组是布尔数组,则可以选择使用数字数据类型,其中数字的每个二进制位对应于数组版本中的布尔值。
可以预料,此方法将比strinfigication选项更有效,因为数据类型转换显然需要一些时间。
这是原始数组模式的运行:
let arr = [false,true];
if (!arr[0] && arr[1] && !arr[2]) console.log("do A");
if (!arr[0] && !arr[1] && arr[2]) console.log("do B");
if (arr[0] && arr[1] && !arr[2]) console.log("do C");
以下是使用位集实现的相同逻辑:
let bitset = 0b001;
if (bitset === 0b010) console.log("do A");
if (bitset === 0b001) console.log("do B");
if (bitset === 0b110) console.log("do C");
如果您需要的位数多于number数据类型(53位)中的可用位数,则可以使用BigInt。例如:
let bitset = 0b1010101010101010101010101010101010101010101010101010101n;
// A partial comparison
if ((bitset & 0b100010001n) === 0b100010001n) console.log("do A");
当然,不必使用0b
文字;这只是为了突出显示与数组版本的对应关系。您可以通过以十六进制(0x
)或什至纯十进制数写数字来保存一些字符,尽管后者对于您的代码阅读者来说比较晦涩。