判断值是否不同
Determine if values are different
假设我有 4 个变量
bool value1 = false;
bool value2 = false;
bool value3 = true;
bool value4 = false;
而且它们都没有相同的值(都是真的 ||
都是假的)
我找到了 2 种方法,反正其中 none 看起来很容易理解。
bool areDifferent = !(value1 == value2 == value3 == value4);
和
bool areDifferent = new[] { value1, value2, value3, value4 }.Distinct().Count() > 1;
问题:是否有其他方法,在可读性/可理解性方面更好?
尽管就个人而言,我更喜欢您的第一种方法,但以下方法也适用。
bool value1 = false;
bool value2 = false;
bool value3 = true;
bool value4 = false;
var values = new[] { value1, value2, value3, value4 };
bool areDifferent = values.Any(v => v) && values.Any(v => !v);
为了可读性和理解,我会交换逻辑。当您检查值是否不同时,并不清楚 - 所有值都应该不同(考虑整数值 1、2、3),或者值可能相等,但至少有一个不同的值(1、2、1)?当您检查所有值是否相等时,它总是很清楚。
我会将此逻辑提取到命名良好的方法中(如果需要,您甚至可以将其设为通用):
public static bool AllEqual(params bool[] values)
{
if (values.Length == 0)
return true;
var first = values[0];
for (int i = 1; i < values.Length; i++)
if (values[i] != first)
return false;
return true;
}
和用法
var notAllEqual = !AllEqual(value1, value2, value3, value4);
使用声明式方法,您的代码描述您正在做什么,而不是告诉如何和让 reader 自行理解是什么。
更新:如果你总是处理四个布尔值,检查它们是否不相等的最简单方法是
(value1 ^ value2) || (value2 ^ value3) || (value3 ^ value4)
但是就可读性而言,任何命令式的方式都比声明式的差
你可以把位组合起来检查
int value = (value1 ? 8 : 0) |
(value2 ? 4 : 0) |
(value3 ? 2 : 0) |
(value4 ? 1 : 0);
return value != 0 && value != 15;
为了便于理解,我们可以创建一个方法并使用 if 块。
public bool areDifferent(bool value1, bool value2, bool value3, bool value4)
{
if(value1 == value2)
if(value2 == value3)
if(value3 == value4)
return false;
return true;
}
也许 Linq 的声明性足够了?
var values = new[] { false, false, true, false };
bool notAllEqual = values.Any(x => x != values.First());
或者:
var values = new[] { false, false, true, false };
bool allEqual = values.All(x => x == values.First());
if (!allEqual)
{
// They are different
}
你说你想检查你的元素是否不
all are true || all are false
给定一个列表
var values = new List<bool> { value1, value2, value3, value4 };
这些元素,代码中最接近的表示形式是:
var areDifferent = !(values.All(v => v == true) || values.All(v => v == false));
虽然在可读性方面,我更喜欢:
var areEqual = values.All(v => v == true) || values.All(v => v == false);
稍后检查:
if (!areEqual)
{
// Do something
}
但这只是个人喜好。
我觉得这有点代码味道,您可能需要重构代码而不是寻找更好的方式来显示布尔值。
如果不提供实际代码,您将始终得到假设而不是答案。
无论如何,关于您的具体问题,您可以创建一个 public static class
并将其用作结果测试器来验证您代码中的所有类型的结果。这样,您可以重复使用它,而且可读性也会更好。
例如:
public static class Validate
{
public static bool AreEqual(params bool[] values) => AreTrue(values) || AreFalse(values);
public static bool AreTrue(params bool[] values) => values.All(x => x == true);
public static bool AreFalse(params bool[] values) => values.All(x => x == false);
}
然后像这样使用它:
bool value1 = false;
bool value2 = false;
bool value3 = true;
bool value4 = false;
if(Validate.AreEqual(value1 , value2 , value3 , value4))
{
// do something
}
通用方法:
static bool AreDifferent(params bool[] values)
{
var tmp = values.Select((value, index) => value ? 1 << index : 0).Aggregate((i, j) => i | j);
return tmp != 0 && tmp != (1 << values.Length) - 1;
}
假设我有 4 个变量
bool value1 = false;
bool value2 = false;
bool value3 = true;
bool value4 = false;
而且它们都没有相同的值(都是真的 ||
都是假的)
我找到了 2 种方法,反正其中 none 看起来很容易理解。
bool areDifferent = !(value1 == value2 == value3 == value4);
和
bool areDifferent = new[] { value1, value2, value3, value4 }.Distinct().Count() > 1;
问题:是否有其他方法,在可读性/可理解性方面更好?
尽管就个人而言,我更喜欢您的第一种方法,但以下方法也适用。
bool value1 = false;
bool value2 = false;
bool value3 = true;
bool value4 = false;
var values = new[] { value1, value2, value3, value4 };
bool areDifferent = values.Any(v => v) && values.Any(v => !v);
为了可读性和理解,我会交换逻辑。当您检查值是否不同时,并不清楚 - 所有值都应该不同(考虑整数值 1、2、3),或者值可能相等,但至少有一个不同的值(1、2、1)?当您检查所有值是否相等时,它总是很清楚。
我会将此逻辑提取到命名良好的方法中(如果需要,您甚至可以将其设为通用):
public static bool AllEqual(params bool[] values)
{
if (values.Length == 0)
return true;
var first = values[0];
for (int i = 1; i < values.Length; i++)
if (values[i] != first)
return false;
return true;
}
和用法
var notAllEqual = !AllEqual(value1, value2, value3, value4);
使用声明式方法,您的代码描述您正在做什么,而不是告诉如何和让 reader 自行理解是什么。
更新:如果你总是处理四个布尔值,检查它们是否不相等的最简单方法是
(value1 ^ value2) || (value2 ^ value3) || (value3 ^ value4)
但是就可读性而言,任何命令式的方式都比声明式的差
你可以把位组合起来检查
int value = (value1 ? 8 : 0) |
(value2 ? 4 : 0) |
(value3 ? 2 : 0) |
(value4 ? 1 : 0);
return value != 0 && value != 15;
为了便于理解,我们可以创建一个方法并使用 if 块。
public bool areDifferent(bool value1, bool value2, bool value3, bool value4)
{
if(value1 == value2)
if(value2 == value3)
if(value3 == value4)
return false;
return true;
}
也许 Linq 的声明性足够了?
var values = new[] { false, false, true, false };
bool notAllEqual = values.Any(x => x != values.First());
或者:
var values = new[] { false, false, true, false };
bool allEqual = values.All(x => x == values.First());
if (!allEqual)
{
// They are different
}
你说你想检查你的元素是否不
all are true || all are false
给定一个列表
var values = new List<bool> { value1, value2, value3, value4 };
这些元素,代码中最接近的表示形式是:
var areDifferent = !(values.All(v => v == true) || values.All(v => v == false));
虽然在可读性方面,我更喜欢:
var areEqual = values.All(v => v == true) || values.All(v => v == false);
稍后检查:
if (!areEqual)
{
// Do something
}
但这只是个人喜好。
我觉得这有点代码味道,您可能需要重构代码而不是寻找更好的方式来显示布尔值。
如果不提供实际代码,您将始终得到假设而不是答案。
无论如何,关于您的具体问题,您可以创建一个 public static class
并将其用作结果测试器来验证您代码中的所有类型的结果。这样,您可以重复使用它,而且可读性也会更好。
例如:
public static class Validate
{
public static bool AreEqual(params bool[] values) => AreTrue(values) || AreFalse(values);
public static bool AreTrue(params bool[] values) => values.All(x => x == true);
public static bool AreFalse(params bool[] values) => values.All(x => x == false);
}
然后像这样使用它:
bool value1 = false;
bool value2 = false;
bool value3 = true;
bool value4 = false;
if(Validate.AreEqual(value1 , value2 , value3 , value4))
{
// do something
}
static bool AreDifferent(params bool[] values)
{
var tmp = values.Select((value, index) => value ? 1 << index : 0).Aggregate((i, j) => i | j);
return tmp != 0 && tmp != (1 << values.Length) - 1;
}