对数组进行字符串化是个好习惯吗?

问题描述

假设我有一个包含布尔值的数组。

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]”。但是,由于您仅使用falsetrue,所以这不是问题。

现在您的问题是

这被认为是好的做法吗?

这是见仁见智。我的第一个直觉说“不”,主要是因为类型转换,但是由于没有针对您的特定用例(即布尔数组)的警告,因此我们实在没有什么可批评的。

使用此方法可能会遇到任何隐藏的错误吗?

此方法会增加可读性吗?

但是,至少有一种替代方法具有所有相同的优点,但不依赖于某些数据类型转换:

替代:位集

如果您的数组是布尔数组,则可以选择使用数字数据类型,其中数字的每个二进制位对应于数组版本中的布尔值。

可以预料,此方法将比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)或什至纯十进制数写数字来保存一些字符,尽管后者对于您的代码阅读者来说比较晦涩。