【问题标题】:C#: How to check if all the elements in an array of boolean variables are of the same value (All true or All false)?C#:如何检查布尔变量数组中的所有元素是否具有相同的值(全部为真或全部为假)?
【发布时间】:2014-06-05 13:12:08
【问题描述】:

我有一个布尔变量数组,如果这个数组中的所有元素都具有相同的值,我想返回 true,否则返回 false。我知道我可以遍历所有元素,但我想知道 C# 中是否有更快的方法。

【问题讨论】:

  • 您使用的任何方法归结为检查每个元素;没有办法解决这个问题。循环遍历元素,如果任何元素与第一个元素不匹配,则返回 false。
  • imo prrprcupofcoffee的做法是最快的,退出循环才是最快的

标签: c# arrays


【解决方案1】:
var allAreTheSame = myArray.All(a => a) || myArray.All(a => !a)

【讨论】:

  • 这并不比OP提出的解决方案快
  • @dcastro 如果 All 命中一个不满足谓词的成员,它就会停止迭代,所以是的。
  • 假设他的提议不包括那张支票 - 他过于含糊。但是,很公平。
【解决方案2】:
var result = array.Distinct().Count() == 1;

【讨论】:

  • @Ani 一个不同的布尔值永远不会返回超过 2 个值。
  • 呃,是的。脑筋急转弯。
  • @JimMischel - Distinct().Count()0 对于空数组,所以这将返回 false。
  • @Lee 我认为确定所有元素是否相同对于没有元素的数组没有意义。我认为这种情况应该由单独的代码路径来处理。
  • @MarkO - 它确实有意义并且应该返回 true,就像 Enumerable.All 对空集合所做的一样。如果这个应用程序确实是一个错误,它应该抛出一个异常。
【解决方案3】:
// Assuming the array is NOT empty
// Get first value
var firstValue = myArray.First();

// Check if all other values are identical
var allidentical = myArray.Skip(1).All(z => z == firstValue);

【讨论】:

  • 最有效,您可以在开始时添加一个快速的一次性检查。大多数其他解决方案在数组上​​循环两次。
【解决方案4】:
Enumerable.Range(0, array.Length-1).All(i => array[i] == array[i+1])

编辑:在 cmets 之后修复

Enumerable.Range(1, array.Length).All(i => array[i] == array[0])

【讨论】:

  • 这会在空数组上引发异常。
  • 是的。 Enumerable.Range(1, array.Length).All(i => array[i] == array[0]) then.
  • 当您尝试访问数组的索引 0 时仍然会抛出该错误。
  • 如果数组为空或有 1 个元素,则不会计算 All(...)
  • 如果数组为空,则Enumerable.Range将抛出,因为计数为负数。
【解决方案5】:
var allAreTheSame = myArray.Distinct().Count() == 1

只是 David 方法的一种替代方法,略短且可能更有效,因为我认为枚举数组合将导致 Array 仅循环一次。

【讨论】:

  • 看看@MarkO 的回答
【解决方案6】:

我会选择扩展方法。我永远喜欢这些方法:

包含扩展方法的类将是:

public static class ExtensionMethods
{
    public static bool AreAll<T>(this T[] source, Func<T, bool> condition)
    { return source.Where(condition).Count() == source.Count(); }

    public static bool AreAllTheSame<T>(this IEnumerable<T> source)
    { return source.Distinct().Count() == 1; }
}

您看到我有 2 种扩展方法,一种采用 Func,一种不采用参数。

当你想检查数组中的所有元素是否具有相同的值时调用第一个(例如,所有元素都为真,或者所有元素都为假)。

当您不想检查特定参数但只想查看所有值是否相同时,将调用第二个。

还有一个小演示来演示扩展方法本身:

class Program
{
    static void Main(string[] args)
    {
        bool[] array = { true, false, true, false, true };
        bool[] trueArray = { true, true, true, true };

        Console.WriteLine("Searching with a predicate:");
        Console.WriteLine(array.AreAll(x => x).ToString());
        Console.WriteLine(array.AreAll(x => !x).ToString());
        Console.WriteLine(trueArray.AreAll(x => x).ToString());
        Console.WriteLine(trueArray.AreAll(x => !x).ToString());

        Console.WriteLine("Searching without a predicate:");
        Console.WriteLine(array.AreAllTheSame().ToString());
        Console.WriteLine(array.AreAllTheSame().ToString());
        Console.WriteLine(trueArray.AreAllTheSame().ToString());
        Console.WriteLine(trueArray.AreAllTheSame().ToString());

        Console.ReadLine();
    }
}

这将产生以下输出:

希望对您有所帮助。

【讨论】:

  • 这只是Enumerable.All 的不太通用的实现和Array.TrueForAll 的重新实现。这仍然无济于事,因为您需要在谓词中使用第一个值。
  • 感谢提及。
  • 我已经修改了代码和示例。现在提供 2 个正在处理 IEnumerable 的函数。一个带谓词,另一个不带谓词。
  • 正确,没有检查。
【解决方案7】:

只是为了好玩一点不同的解决方案:

!(array.Any(b => b) && array.Any(b => !b));

这里有两个循环。其中一个应该在数组中的第一个元素上退出。另一个应该在第一次出现不同于数组中的第一次出现时退出。对于空数组,它也会返回 true。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    • 2023-03-26
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多