2017-07-02 72 views
2
if (boolThing[0] == true 
     && boolThing[2] == true 
     && !boolThing[1] 
     && !boolThing[3] 
     && !boolThing[4]) 
    { 
     Debug.Log("Hey"); 
    } 

我想了解如何执行此操作的不同方法。仅检查数组或列表中的特定布尔值

当0和3为真而其余为假时,代码执行某些操作。

是否有“更清洁”或“更有效”的方式来做到这一点?

+1

'boolThing [0] == true'只能是'boolThing [0]'。 '== true'是多余的。 – Guy

回答

1

你不需要if(boolThing[0]==true)。你可以使用`if(boolThing [0]))

你也可以使用二元运算符一起评估几个布尔值。

if((bools[0]&bools[3]) && !(bools[1]|bools[2]|bools[4]|bools[5]) 

可以使用BitArray轻松地与布尔的采集工作,这将是更有效的。

最有效的方法将是使用数字类型。

最简单的方法是使用枚举和标志。您可以使用二元运算符来设置或清除枚举的标志。

[Flags] 
public enum MyBoolFlag 
{ 
    None, 
    Bool0 = 1<<0, 
    Bool1 = 1 << 1, 
    Bool2 = 1 << 2, 
    Bool3 = 1 << 3, 
    Bool4 = 1 << 4, 
    Bool5 = 1 << 5, 
    //etc 
} 

而你使用二进制操作来设置标志。

MyBoolFlag myFlag = MyBoolFlag.Bool0|MyBoolFlag.Bool1|MyBoolFlag.Bool3; 

在您的代码,您现在可以检查:

if(myFlag == MyBoolFlag.Bool0|MyBoolFlag.Bool3) 
{ 

} 

您可以定义常量各种条件。

const MyBoolFlag myCondition1 = MyBoolFlag.Bool0|MyBoolFlag.Bool3; 

再检查:

if(myFlag == myCondition1) 
{ 

} 

你也可以做一些更多的跑腿和使用类型,如原生类型,字节和直接诠释。

您可以使用一个字节来保存8个布尔值作为标志掩码,每个掩码表示2的幂。 uint32可以保存32,而uint64可以保存64个布尔值。

这有巨大的性能提升,因为布尔值被存储为uint32,这意味着它使用4个字节的数据,并且当您使用位请求布尔标志时,您可以在uint32中打包32个布尔值。

程序也将执行得更快,因为CPU在使用本地机器字的单个操作中评估myFlag == myCondition1。否则,需要很多指令来将查找布尔值置于数组中并进行比较。 。Net也会做一些健全的检查,确保你的数组不是空的,你的索引不超出范围,然后需要移动指针来查找这些值。

为了方便起见,您可以从布尔值数组中创建一个bitarray,然后使用它来设置适当的标志位来初始化一个数值类型的数组。

例如:

bool[] bools = new bool[] { true, false, false, true, false, false }; 
BitArray bitArray = new BitArray(new bool[] { true, false, false, true, false, false }); 
int[] array = new int[1]; 
bitArray.CopyTo(array, 0); 
int value = array[0]; 

的这点是 '价值' 将是9,如果布尔变量[0] =真及的bool [3]真。

所以,你的代码将干净是:

if(value==9) // bools[0]&bools[1]==true; 

您还可以创建不断口罩检查不同的数值,以检查是否不同位在数值设定或使用二进制运算操作的位。

通过使用二元运算设置数值,可以获得更高的效率。

uint32 myFlag= 1|(1<<3); 
+0

在你的例子'(bools [0]&bools [3])&&!(bools [1] | bools [2] | bools [4] | bools [5])''在开始时,不需要“单个“'&'和'|'运算符。这是浪费,只需在那里使用'&&'和'||'。 –

+1

'&&'会起作用,但需要三个操作来评估第一组是否为真,但'&'需要一个。使用'&&'第一个操作检查bools [0]是否为真,第二个如果bools [1]为真,第三个是paranthesis中的'&&'操作符。使用'&'二元运算将bools [0]和bools [1]合并为一个结果,然后评估它是否为真。你可以编码并查看VS中的反汇编来验证。由于使用“||”,下半年还会有更多的jmp。您可以使用两百万次运行循环来验证。 –

+0

有趣。在你的百万次验证循环中,“bools”的内容每次都相同吗?为什么不在'final'中间操作中使用'&',如果你在括号内部执行它?短路和非短路的混合看起来很奇怪。如果我拿出子表达式'bools [1] | bools [2] | bools [4] | bools [5])'作为例子,你必须检查所有的数组条目,即使'bools [1] '已经是'true'。但检查数组条目非常快,所以这是一个特殊情况。 “||”之前的'|'链应该多久才能更有效率? –

2

你能做到这一点,在Unity

if(boolThing.SequenceEqual(new bool[] { true, false, true, false, false}) 
{ 
Debug.Log("Hey"); 
} 
0

命名空间System.Linq的你可以把你的变量在适当的列表中,然后测试每个List它是否只包含一个特定值的元素(truefalse ):

List<bool> thingsTestedForTrue = new List<bool> { boolThing[0], boolThing[1], boolThing[2] }; 
List<bool> thingsTestedForFalse = new List<bool> { boolThing[3], boolThing[4], boolThing[5] }; 

if(thingsTestedForTrue.All(thing => thing == true) && thingsTestedForFalse.All(thing => thing == false) 
{ 
    // All values passed 
}