我正在使用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阵列中,我会变错。
我知道我可以创建一个结果布尔数组并使用循环获取输出,但我问是否有更优雅的方法来获得此结果而不使用太多循环。
答案 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},
};
现在,您可以使用Any
和All
:
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))
...