代码之家  ›  专栏  ›  技术社区  ›  My Other Me

如何测试多个布尔值在C中是否具有相同的值?

  •  9
  • My Other Me  · 技术社区  · 14 年前

    是否有较短的测试方法:

    if (!((a == b) && (a == c) && (a == d) && (a == e) && (a == f)))
    

    我最后写了一个方法让我这样做

    if (!AllEqual(new[] { a, b, c, d, e, f }))
    

    这感觉更好,可读性更高,但我想知道框架中是否已经存在这样的东西?

    8 回复  |  直到 14 年前
        1
  •  13
  •   Jon Skeet    14 年前

    首先,您可以使用参数数组使其更简单:

    public static bool AllEqual<T>(params T[] values)
    ...
    
    
    if (AllEqual(a, b, c, d, e, f))
    {
        ...
    }
    

    老实说,我认为你不会找到比这简单的东西。我在其他任何地方或框架中都没有看到这一点。好吧,我想 在Linq中可以做的事情:

    if (new { a, b, c, d, e, f }.Distinct().Count() == 1)
    

    但那太可怕了:)

    稍微高效的版本是:

    if (!(new { a, b, c, d, e, f }).Distinct().Skip(1).Any()))
    

    …一旦找到第二个不同的元素,它就会返回false。只有6个元素,我认为这不值得担心:)

        2
  •  2
  •   Community CDub    7 年前

    只有当a、b、c、d、e和f是布尔值时:

    最好的办法是看一下 Boolean logic logic gates simplify 你的方程式。

    (The == 就像一个 XNOR gate 对于布尔值)

    举个例子:

    (!((a == b) && (a == c) && (a == d) && (a == e) && (a == f)))
    

    与以下内容相同:

    ((a^b) || (a^c) || (a^d) || (a^e) || (a^f))
    

    但我认为,这一定是一个有趣的做法,以一个逻辑的革命,来达到这一点。

    [编辑]与 Hightechrider's answers ,建议

    ((a^b)(a^c)(a^d)(a^e)(a^f))
    

    相当于:

    ((a != b) || (a != c) || (a != d) || (a != e) || (a != f))
    

    但是 Hightechrider's proposition 即使A、B、C、D、E和F不是布尔值,也能完美工作。

        3
  •  1
  •   Ian Mercer    14 年前

    你可以分发!在表达式中:

    if ((a != b) || (a != c) || (a != d) || (a != e) || (a != f)))
    

    你也可以用 Any 或者! All 而不是添加新方法。

    if (new[]{b, c, d, e, f}.Any(x => x != a)) ...
    
        4
  •  1
  •   Ramiz Uddin    14 年前

    使用 BitArray :

    管理一个紧凑的位值数组, 它们被表示为布尔, 其中,true表示位是 ON(1)和FALSE表示位为 关闭(0)。

    // Your collection of bits
    bool a = false, b = false, c = false;
    // get them into an array
    bool[] d = new bool[] { a, b, c };
    // intialize BitArray with that array
    System.Collections.BitArray e = new System.Collections.BitArray(d);
    // use OfType<>, Any<>, All<>
    if (Convert.ToBoolean(e.OfType<bool>().Any<bool>(condition => condition.Equals(true)) && e.OfType<bool>().Any<bool>(condition => condition.Equals(false)))) Console.WriteLine("some one is TRUE!.");
    

    用于演示的示例控制台应用程序代码:

        class Program
        {
            static void Main(string[] args)
            {
                bool a = false, b = false, c = false;
                bool[] d = new bool[] { a, b, c };
                System.Collections.BitArray e = new System.Collections.BitArray(d);
                if (Convert.ToBoolean(e.OfType<bool>().Any<bool>(condition => condition.Equals(true)) && e.OfType<bool>().Any<bool>(condition => condition.Equals(false)))) Console.WriteLine("some one is TRUE!.");
                if (Convert.ToBoolean(e.OfType<bool>().Any<bool>(condition => condition.Equals(true)) && e.OfType<bool>().Any<bool>(condition => condition.Equals(false)))) Console.WriteLine("some one is FALSE!.");
                if (Convert.ToBoolean(e.OfType<bool>().All<bool>(condition => condition.Equals(true)))) Console.WriteLine("All of them are TRUE!.");
                if (Convert.ToBoolean(e.OfType<bool>().All<bool>(condition => condition.Equals(false)))) Console.WriteLine("All of them are false!.");
                Console.ReadLine();
            }
        }
    

    有关的msdn文档 BitArray

        5
  •  1
  •   Shadow Wizard    14 年前

    怎么样。。

    List<bool> arr = new List<bool>{ a, b, c, d, f };
    bool allEqual = arr.TrueForAll(x => { return x; }) || arr.TrueForAll(x => { return !x; });
    

    我觉得很优雅。:)

        6
  •  1
  •   Grodriguez    14 年前

    你可以用这个来检查它们是否都是真的:

    if (a && b && c && d && e && f) {
        ...
    }
    

    为了检验它们是否都是假的:

    if (!(a || b || c || d || e || f)) {
        ...
    }
    

    你可以把两者结合起来检查它们是否相等:

    if ((a && b && c && d && e && f) || !(a || b || c || d || e || f))
        ...
    }
    

    但坦率地说,这并不比你原来的解决方案好多少——)

    基于以上,这里是 AllEqual :

    public static bool AllEqual(bool[] values)
    {
        bool andTerm = true;
        bool orTerm = false;
        foreach (bool v in values)
        {
            andResult &= v;
            orResult |= v;
        }
        return andTerm || !orTerm;
    }
    
        7
  •  0
  •   Simone    14 年前

    我不认为只为框架引入依赖性是个好主意。

        8
  •  0
  •   Kate Gregory    14 年前

    这不是人们通常想知道的。你可以很容易地通过简单地把它们放在一起来检验它们是否都是真的,或者通过把它们放在一起来检验它们是否都是假的。它在C++中也很受欢迎,将BOOLS投射到int并添加它们——在你的情况下,你会寻找总共6到0个。但是我认为这两个都会掩盖你知道6个标志要么都是真的要么都是假的任何商业理由。