【问题标题】:How to get true if all the array elements in the same position are true如果同一位置的所有数组元素都为真,如何获得真
【发布时间】:2016-05-13 17:58:24
【问题描述】:

我正在使用 n 个布尔数组,如下所示:

A  = [1, 1, 0, 1]
A1 = [0, 1, 0, 1]
A2 = [0, 1, 0, 0]

B  = [1, 1, 0, 1]
B1 = [0, 0, 0, 1]
B2 = [0, 1, 0, 0]

我正在开发一个函数,如果存在至少一个 1(例如,在三个 A 数组中,我会得到 true,因为 A[1] = A1[1] = A2[1] = true)返回 true 在 B 数组中,我会得到 false。

我知道我可以创建一个结果布尔数组并通过循环获得输出,但我想问是否有更优雅的方法来获得此结果而无需使用太多循环。

【问题讨论】:

  • 所有数组的长度都一样吗?列可以是任意的吗?
  • 也许您可以将数组转换为二进制表示,然后执行 AND 操作并检查结果是否为 0!但我不认为这比你的方法更好!
  • @Grundy 列的长度必须相同,并且只能是布尔值

标签: c# arrays loops for-loop boolean


【解决方案1】:

虽然这种转换过程远非最快,但我更愿意将这种情况视为一组二进制位,而不是一系列布尔值 - 此时二进制 AND 将为您提供答案:

int ToInt(IEnumerable<bool> bits) => bits.Select((b, i) => ((b ? 1 : 0) << i))
                                         .Aggregate((b, b1) => (b | b1));    

bool HasCommonBits(params <IEnumerable<bool>[] seqs) => 
     seqs.Aggregate((s, i) => s.ToInt() & i) > 0;
...

if(HasCommonBits(A, A1, A2))
...

【讨论】:

    【解决方案2】:

    the accepted answer 有点不同,因为它使用boolean[][]

    您的示例数组:

    bool[][] boolArrays1 = { 
                               new[]{true, true, false, true}, 
                               new[]{false, true, false, true}, 
                               new[]{false, true, false, false}, 
                           };
    bool[][] boolArrays2 = { 
                               new[]{true, true, false, true}, 
                               new[]{false, false, false, true}, 
                               new[]{false, true, false, false}, 
                           };
    

    现在您可以使用AnyAll 的组合:

    bool anyColumnTrue1 = Enumerable.Range(0, boolArrays1.Min(arr => arr.Length))
        .Any(ix => boolArrays1.All(arr => arr[ix]));  // true
    bool anyColumnTrue2 = Enumerable.Range(0, boolArrays2.Min(arr => arr.Length))
        .Any(ix => boolArrays2.All(arr => arr[ix]));  // false
    

    既然你已经要求一个方法,你可以使用这个扩展方法,它支持可以以任何序列存储的数组和列表:

    public static bool AnyColumnTrue(this IEnumerable<IList<bool>> bools) 
    {
        if (bools == null) throw new ArgumentNullException("bools");
    
        return Enumerable.Range(0, bools.Min(seq => seq.Count))
            .Any(ix => bools.All(arr => arr[ix]));
    }
    

    那么简单易读:

    bool anyColumnTrue = boolArrays1.AnyColumnTrue();
    

    如果您实际上有数组变量而不是集合,您仍然可以轻松使用我的方法:

    bool anyColumnTrue = new[]{ A, A1, A2 }.AnyColumnTrue();
    

    【讨论】:

      【解决方案3】:

      试试这个代码,方法不依赖于数组的数量:

      class Program
      {
          public static bool[] Convert(params bool[][] args)
          {            
              return (new List<bool[]>(args)).Aggregate((a, b) => a.Select((x, i) => x && b[i]).ToArray());
          }
      
          static void Main(string[] args)
          {
              var A = new[] { true, true, false, true };
              var A1 = new[] { false, true, false, true };
              var A2 = new[] { false, true, false, false };
              var A3 = new[] { true, true, true, true };
      
              var res = Convert(A, A1, A2, A3);
          }
      }
      

      【讨论】:

        【解决方案4】:

        使用 Linq 的另一种选择:

        var anyColumnAllTrue = A.Select((value, index) => 
            value && A1[index] && A2[index])
        .Any(result => result);
        

        【讨论】:

          【解决方案5】:

          我为此建议一个提取方法(你可以在其中放置任意数量的任意长度的数组):

              private static Boolean HasOnes(params Boolean[][] items) {
                for (int i = items.Min(line => line.Length) - 1; i >= 0; --i)
                  if (items.All(line => line[i]))
                    return true;
          
                return false;
              }
          
          ....
          
              Boolean[] A =  { true, true, false, true };
              Boolean[] A1 = { false, true, true, true };
              Boolean[] A2 = { false, true, false, false };
          
              Console.Write(HasOnes(A, A1, A2) ? "Yes" : "No");
          
              Boolean[] B  = {true, true, false, true};
              Boolean[] B1 = {false false, false, true};
              Boolean[] B2 = {false, true, false, false};
          
              Console.Write(HasOnes(B, B1, B2) ? "Yes" : "No");
          

          【讨论】:

            【解决方案6】:

            以下允许您指定任意数量的数组

            class Program
                {
                    static void Main(string[] args)
                    {
                        var A = new bool[] { true, true, false, true };
                        var A1 = new bool[] { false, true, false, true };
                        var A2 = new bool[] { false, true, false, false };
            
                        var B = new bool[] { true, true, false, true };
                        var B1 = new bool[] { false, false, false, true };
                        var B2 = new bool[] { false, true, false, false };
            
                        Console.WriteLine(AtLeastOneColumnIsTrue(A, A1, A2));
                        Console.WriteLine(AtLeastOneColumnIsTrue(B, B1, B2));
            
                        Console.ReadLine();
                    }
            
                    public static bool AtLeastOneColumnIsTrue(params bool[][] boolArrays)
                    {
                        for (int column = 0; column < boolArrays[0].Length; column++)
                        {
                            var columnIsAllTrue = true;
            
                            for (int boolArray = 0; boolArray < boolArrays.Length && columnIsAllTrue; boolArray++)
                            {
                                columnIsAllTrue = columnIsAllTrue && boolArrays[boolArray][column];
                            }
            
                            if (columnIsAllTrue)
                            {
                                return true;
                            }
                        }
            
                        return false;
                    }
                }
            

            【讨论】:

              【解决方案7】:

              这样的事情可以解决问题:

              bool[] A = ...;
              bool[] A1 = ...;
              bool[] A2 = ...;
              
              var length = Math.Min(Math.Min(A.Length, A1.Length), A2.Length);
              var result = Enumerable.Range(0, length).Any(i => A[i] && A1[i] && A2[i]);
              

              如果你事先知道长度是多少,你可以跳过长度计算,这会减少一条线。

              【讨论】:

                猜你喜欢
                • 2016-05-03
                • 2012-10-12
                • 2022-11-25
                • 2020-06-24
                • 1970-01-01
                • 2018-01-24
                • 2013-09-09
                • 2021-10-15
                • 2013-09-12
                相关资源
                最近更新 更多