I have an 2d array and I have no idea how I can delete the rows and columns from it in which are only zero's.
int [,] test = { {0, 0, 0, 0},
{0, 0, 1, 1},
{0, 1, 1, 0},
{0, 0, 0, 0} }
int row = pieces.GetLength(0);
int col = pieces.GetLength(1);
for (int y = 0; y < row; y )
{
for (int x = 0; x < col; x )
{
if (pieces[y,x] == 0)
{
}
}
}
So I want it to be this:
int [,] test = { {0, 1, 1},
{1, 1, 0}}
CodePudding user response:
Here this will remove every Column/Row with only zero
int[][] test = { new int[]{0, 0, 0, 0},
new int[]{0, 0, 1, 1},
new int[]{0, 1, 1, 0},
new int[]{0, 0, 0, 0} };
var result =
Transpose(Transpose(test.Where(row => !row.All(item => item == 0)).ToArray()).Where(row => !row.All(item => item == 0)).ToArray())
.ToArray();
This basically selects the rows where there isn't a single 0. Now transpose the matrix(its easier to not select rows than not selecting columns) and again select every row where there isn't any 0(meaning there is at least a 1 we need), now transpose back to original order.
here are the helper methods
static int[][] Transpose(int[][] originalArray)
{
int w = originalArray.Length;
int h = originalArray[0].Length;
int[][] result = CreateJaggedArray<int[][]>(h, w);
for (int i = 0; i < originalArray.Length; i )
for (int j = 0; j < originalArray[i].Length; j )
{
result[j][i] = originalArray[i][j];
}
return result;
}
static T CreateJaggedArray<T>(params int[] lengths)
{
return (T)InitializeJaggedArray(typeof(T).GetElementType(), 0, lengths);
}
static object InitializeJaggedArray(Type type, int index, int[] lengths)
{
Array array = Array.CreateInstance(type, lengths[index]);
Type elementType = type.GetElementType();
if (elementType != null)
{
for (int i = 0; i < lengths[index]; i )
{
array.SetValue(
InitializeJaggedArray(elementType, index 1, lengths), i);
}
}
return array;
}
you can convert them to extensions if you want since they are static anyway.
Check out the complete example at dotnetfiddle
CodePudding user response:
Ok i created a code, that will first create List<int>
out of each row and column, and add its indexes to another List<int>
that will mark columns and rows at which '1' does appear. This code uses Linq, to check .Contains()
if 1 does exists. Rest should be fairly easy to read.
int[,] test = { {0, 0, 0, 0},
{0, 0, 1, 1},
{0, 1, 1, 0},
{0, 0, 0, 0}};
//get size
int columns = test.GetLength(0);
int rows = test.Length / columns;
//create lists
List<int> nonZeroRows = new List<int>();
List<int> nonZeroColumns = new List<int>();
for (int row = 0; row < rows; row )
{
List<int> rowAsList = new List<int>();
List<int> columnAsList = new List<int>();
for (int col = 0; col < columns; col )
{
rowAsList.Add(test[row, col]);
columnAsList.Add(test[col, row]);
}
//check if row & column contains 1
if(rowAsList.Contains(1))
{
nonZeroRows.Add(row);
}
if (columnAsList.Contains(1))
{
nonZeroColumns.Add(row);
}
}
//create new array
int[,] result = new int[nonZeroRows.Count, nonZeroColumns.Count];
int irow = 0;
foreach(int row_id in nonZeroRows)
{
int icol = 0;
foreach (int col_id in nonZeroColumns)
{
result[irow,icol] = test[row_id, col_id];
icol ;
}
irow ;
}