# Generate a matrix of booleans from another one

Let's say that I have a bool[,] with random values

FFFFFFFF
FFFFFTTT
TTTTTTTT
FFFFFFFF


What would be the smartest way to create a new bool[,] that build on top of the previous one. That means, that it can have random values where the previous one was true, but that it preserves the falses from the original?

So this could be a possible result

FFFFFFFF
FFFFFTFT
TTFFFTTT
FFFFFFFF


But this not...

TTTTTFFF
TTTTTFFF
TTTTTTTT
FFFFFFFF


So far I have come with the classical solution. First create a matrix of random values, and the overwrite them.

for (int x = 0; x < cols; x++)
for (int y = 0; y < rows; y++)
if (matrix1[x, y] == false)
matrix2[x, y] = false;


But I was wondering if there is a better way.

• So this is about copying false values from one matrix to the other? – t3chb0t Feb 18 '17 at 21:57
• Well, that is the way that I did it. But I was wondering if there was a more ellegant way to generate the second matrix from the first one. I want to do sort of "Boolean Pyramids" if that makes sense – Enrique Moreno Tent Feb 18 '17 at 22:10

## 1 Answer

You can make this function more generic so that you can use reuse it where necessary and with any type. Currently your code is doing three things:

• Loop over the matrix.
• Checking a condition.
• Modifying the elements.

This can be separated and encapsulated. You first create a general-purpose extension that just loops over any matrix, checks the passed predicate and calls the action:

public static T[,] ForEach<T>(
this T[,] m,
Func<T, bool> predicate,
Action<T, int, int> action
)
{
for (int x = 0; x < m.GetLength(0); x++)
for (int y = 0; y < m.GetLength(1); y++)
if (predicate(m[x, y])) action(m[x, y], x, y);

return m;
}


Example:

Assuming you have these two matrices

var m1 = new[,]
{
{ false, false, false, false },
{ false, true, false, true },
{ true, true, false, false },
{ false, false, true, true }
};

var m2 = new[,]
{
{ false, true, true, false },
{ false, true, false, true },
{ true, true, false, false },
{ false, false, false, false }
};


you call the new ForEach extension like this where you first filter the items with !m so that you get only those where m = false, then you update the second matrix at the coordinates [x, y] with the value m of the first matrix.

m1.ForEach(m => !m, (m, x, y) => m2[x, y] = m);