如果同一位置的所有数组元素都为真,则如何获得

时间:2016-02-04 08:09:54

标签: c# arrays loops for-loop boolean

我正在使用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,则返回true(例如,在三个A数组中,我将得到真,因为A[1] = A1[1] = A2[1] = true) 在B阵列中,我会变错。

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

7 个答案:

答案 0 :(得分:6)

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

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]);

如果您事先知道长度是多少,您可以跳过长度计算。这将占用一条线。

答案 1 :(得分:1)

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

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;
        }
    }

答案 2 :(得分:1)

试试这段代码,方法不取决于数组的数量:

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);
    }
}

答案 3 :(得分:1)

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();

答案 4 :(得分:1)

我建议使用提取的方法(并且可以放置任意数量的任意长度的数组):

keydown

答案 5 :(得分:1)

使用Linq的另一种选择:

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

答案 6 :(得分:0)

虽然这个转换过程远非最快,但我更倾向于将这种情况视为一组二进制位,而不是一系列bool - 此时二进制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))
...