Januszoff
Januszoff

Reputation: 315

Trimming an 2d array of int from unwanted values

I have an array declared like so:

int[,] binaryzacja = new int[bmp2.Width, bmp2.Height];

Where it's dimensions are the dimensions of a picture (usually it's gonna be 200x200). A black pixel is represented by 1. All other pixels are represented by 0.

Let's say my array looks like so:

0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 1 0 1 1 1 0
0 1 1 1 0 0 0
0 0 1 1 0 0 0
0 0 0 0 0 0 0

I want to remove all rows and columns that contain only 0.

So, if my example array was 7 columns, 6 rows; I want a new array that will be 5 columns, 3 rows and look like so:

1 0 1 1 1
1 1 1 0 0
0 1 1 0 0 

Upvotes: 2

Views: 207

Answers (3)

mihai
mihai

Reputation: 4742

You could transform your [,] into a List:

var list = new List<List<int>>();

for (var i = 0; i < binary.GetLength(0); i++ )
{
    var row = new List<int>();
    for(var j = 0; j < binary.GetLength(1); j++)
        row.Add(binary[i, j]);
    list.Add(row);
}

then remove the rows and columns which are all zero:

// Remove the rows
list = list.Where(row => row.Contains(1)).ToList();
// Reverse the matrix and apply the same procedure to remove the columns
list = Transpose(list);
list = list.Where(row => row.Contains(1)).ToList();
// Get back the original order of the rows and columns
list = Transpose(list);

static List<List<int>> Transpose(List<List<int>> input)
{
    return input.ElementAt(0).Select((item, index) => 
        {
            var row = new List<int>{input[0][index]};
            input.ForEach(el => row.Add(el.ElementAt(index)));
            return row;
            }).ToList();
        }
}

and then transform your resulting list back into a [,].

int[,] binaryResult = new int[list.Count(), list.First().Count()];

for (int i = 0; i < binaryResult.GetLength(0); i++)
    for (int j = 0; j < binaryResult.GetLength(1); j++)
        binaryResult[i, j] = list.ElementAt(i).ElementAt(j);

You should extract these into methods, of course.

Upvotes: 3

S&#248;ren
S&#248;ren

Reputation: 11

Without fancy stuff:

int width = binaryzacja.GetLength(0);
int height = binaryzacja.GetLength(1);

int newWidth = width;
int newHeight = height;

int x, y, x2, y2;

for (y = 0; y < height; y++)
{
    if (IsRowEmpty(binaryzacja, y)) newHeight--;
}

for (x = 0; x < width; x++)
{
    if (IsColumnEmpty(binaryzacja, x)) newWidth--;
}

int[,] binaryzacja2 = new int[newWidth, newHeight];


// copy to new array
for (y2 = y = 0; y < height; y++)
{
    if (!IsRowEmpty(binaryzacja, y))
    {
        for(x = x2 = 0; x < width; x++)
        {
            if (!IsColumnEmpty(binaryzacja, x))
            {
                binaryzacja2[x2, y2] = binaryzacja[x, y];
                x2++;
            }
        }
        y2++;
    }
}



bool IsRowEmpty(int[,] array, int y)
{
    for (int x = 0; x < array.GetLength(0); x++)
    {
        if (array[x, y] != 0) return false;
    }
    return true;
}

bool IsColumnEmpty(int[,] array, int x)
{
    for (int y = 0; y < array.GetLength(1); y++)
    {
        if (array[x, y] != 0) return false;
    }
    return true;
}

----- new version:

int width = binaryzacja.GetLength(0);
int height = binaryzacja.GetLength(1);

int newWidth = width;
int newHeight = height;

int[] keepRows = new int[height];
int[] keepColumns = new int[width];

int x, y, x2, y2;
int i;

for (i = y = 0; y < height; y++)
{
    if (IsRowEmpty(binaryzacja, y)) newHeight--;
    else
    {
        keepRows[i] = y;
        i++;
    }
}

for (i = x = 0; x < width; x++)
{
    if (IsColumnEmpty(binaryzacja, x)) newWidth--;
    else
    {
        keepColumns[i] = x;
        i++;
    }
}

int[,] binaryzacja2 = new int[newWidth, newHeight];

// copy to new array
for (y2 = y = 0; y < height; y++)
{
    if(y == keepRows[y2])
    {
        for (x2 = x = 0; x < width; x++)
        {
            if(x == keepColumns[x2])
            {
                binaryzacja2[x2, y2] = binaryzacja[x, y];
                x2++;
            }
        }
        y2++;
    }
}

Upvotes: 1

user2939446
user2939446

Reputation: 71

Loop through the rows, and keep track of the empty ones in an array of some sort. Do the same with the columns.

Using this information, create a new array of the proper rows and columns. Loop through with a double loop. if i is equal to a row in the array, or j is equal to the row in the column, then skip over that value.

Upvotes: 0

Related Questions