C#, rotating 2D arrays - c#

I've looked at other post on rotating 2D arrays, but it's not quite what I want.
I want something like this
int[,] original= new int[4,2]
{
{1,2},
{5,6},
{9,10},
{13,14}
};
I want to turn it like this,
rotatedArray = { {1,5,9,13}, {2,6,10,14}};
I want to do some analysis by column, as opposed to by rows.
This works, but is there an easier way??
private static int[,] RotateArray(int[,] myArray)
{
int org_rows = myArray.GetLength(0);
int org_cols = myArray.GetLength(1);
int[,] myRotate = new int[org_cols, org_rows];
for (int i = 0; i < org_rows; i++)
{
for(int j = 0; j < org_cols; j++)
{
myRotate[j, i] = myArray[i, j];
}
}
return myRotate;
}
Is there an easy way to iterate through columns in c#?
B

If you change your array to be an array of arrays it gets easier. I found this if you change it to an int[][]:
int[][] original = new[]
{
new int[] {1, 2},
new int[] {5, 6},
new int[] {9, 10},
new int[] {13, 14}
};
and the rotate method:
private static int[][] Rotate(int[][] input)
{
int length = input[0].Length;
int[][] retVal = new int[length][];
for(int x = 0; x < length; x++)
{
retVal[x] = input.Select(p => p[x]).ToArray();
}
return retVal;
}

Related

Minimum element of each column in array of arrays

An array of arrays is given. It is necessary to find the minimum element in each column and write the data to a new array. I have done the following implementation, in accordance with the given conditions. But I am having a problem:expected minimum element in each column of the array are incorrect. Where am I making a mistake?
class Program
{
static int[][] Input()
{
Console.Write("n = ");
int n = int.Parse(Console.ReadLine());
int[][] a = new int[n][];
//int[] minA = new int[n];
for (int i = 0; i < n; ++i)
{
a[i] = new int[n];
for (int j = 0; j < n; ++j)
{
Console.Write("a[{0},{1}]= ", i, j);
a[i][j] = int.Parse(Console.ReadLine());
}
}
return a;
}
static void Print(int[] a)
{
foreach (double elem in a)
{
Console.Write("{0} ", elem);
}
}
static void Print2(int[][] a)
{
for (int i = 0; i < a.Length; ++i, Console.WriteLine())
for (int j = 0; j < a[i].Length; ++j)
Console.Write("{0,5} ", a[i][j]);
}
static int[] F(int[][] a)
{
int[] b = new int[a[1].Length];
for (int j = 0; j < a[1].Length; j++)
{
int tempmin = a[0][j];
for (int i = 0; i < a[0].Length; i++)
{
if (a[j][i] <= tempmin)
{
tempmin = a[j][i];
b[j] += tempmin;
}
}
}
return b;
}
static void Main()
{
int[][] myArray = Input();
Print2(myArray);
int[] b = new int[myArray.Length];
b = F(myArray);
Print(b);
}
}
I suggest looping over all lines, while tracking all min columns values:
using System.Linq; // for the final `ToArray()`
...
private static int[] MinColumns(int[][] data) {
if (null == data)
throw new ArgumentNullException(nameof(data));
// List of columns' mins; initially the list is empty
List<int> list = new List<int>();
// for each line (not column!) within jagged array...
foreach (int[] line in data) {
// let's just skip null lines (alternative is to throw exception)
if (null == line)
continue;
// each new line can update columns' max values.
// now we update each column
for (int c = 0; c < line.Length; ++c)
// if index c is too big, i.e.
// the line is too long and some columns appear first time...
if (c >= list.Count)
// ...we just add values of such columns as columns' min
for (int i = list.Count; i <= c; ++i)
list.Add(line[i]);
else
// otherwise we update min values: we compare known min and current value
list[c] = Math.Min(list[c], line[c]);
}
// finally, we convert list into array with ahelp of Linq
return list.ToArray();
}
Note, that here we ignore all holes, e.g. for
int[][] demo = new int[][] {
new int[] {1, 2, 3, 4},
new int[] {5, 6}, // <- hole: we don't have 3d and 4th columns here
new int[] {7, 0, 8},
};
the answer will be {Min(1, 5, 7), Min(2, 6, 0), Min(3, 8), Min (4)} = {1, 0, 3, 4}
Edit: Usage is quite direct; something like this (fiddle yourself)
static void Main()
{
// Get jagged array
int[][] myArray = Input();
// Print it
Print2(myArray);
// Get max for each column
int[] b = MinColumns(myArray);
// Print these maxes
Print(b);
}

Convert multidimensional array to list of single array

I have a multi dimensional array which i need to convert to a list of arrays. Not one single array, but for each iteration of the first dimension i need a separate array containing the values in the second dimension.
How do I convert this:
int[,] dummyArray = new int[,] { {1,2,3}, {4,5,6}};
into a list<int[]> holding two arrays with values {1,2,3} and {4,5,6}?
You can convert 2d array into jagged array and then convert it to List.
int[,] arr = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };
int[][] jagged = new int[arr.GetLength(0)][];
for (int i = 0; i < arr.GetLength(0); i++)
{
jagged[i] = new int[arr.GetLength(1)];
for (int j = 0; j < arr.GetLength(1); j++)
{
jagged[i][j] = arr[i, j];
}
}
List<int[]> list = jagged.ToList();
You can use Linq:
int[,] dummyArray = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };
int count = 0;
List<int[]> list = dummyArray.Cast<int>()
.GroupBy(x => count++ / dummyArray.GetLength(1))
.Select(g => g.ToArray())
.ToList();
You could use for loop like this:
int[,] dummyArray = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };
int size1 = dummyArray.GetLength(1);
int size0 = dummyArray.GetLength(0);
List<int[]> list = new List<int[]>();
for (int i = 0; i < size0; i++)
{
List<int> newList = new List<int>();
for (int j = 0; j < size1; j++)
{
newList.Add(dummyArray[i, j]);
}
list.Add(newList.ToArray());
}
Here is a reusable implementation
public static class Utils
{
public static List<T[]> To1DArrayList<T>(this T[,] source)
{
if (source == null) throw new ArgumentNullException("source");
int rowCount = source.GetLength(0), colCount = source.GetLength(1);
var list = new List<T[]>(rowCount);
for (int row = 0; row < rowCount; row++)
{
var data = new T[colCount];
for (int col = 0; col < data.Length; col++)
data[col] = source[row, col];
list.Add(data);
}
return list;
}
}
and sample usage
var source = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };
var result = source.To1DArrayList();
Some comments on other answers.
M.kazem Akhgary: If I need a list, I don't see why should I first create jagged array and convert it to a list instead of creating list directly.
Eser: I usually like his elegant Linq solutions, but this definitely is not one of them. If the idea is to use Linq (although I strongly believe it's not intended for that), the following would be much more appropriate:
var source = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };
var result = Enumerable.Range(0, source.GetLength(0))
.Select(row => Enumerable.Range(0, source.GetLength(1))
.Select(col => source[row, col]).ToArray())
.ToList();

Combining two single dimensional arrays in a 2D array in c#

I am having two 1D arrays. I want to convert these 2 arrays as single 2D array.
My code is:
public Static void Main()
{
int[] arrayRow;
int[] arrayCol;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
int[,] myArray = new int[row,column];
myArray[i,j] = arrayRow[i]; // not possible -- your suggestions
}
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
Console.Write(myArray[i,j]);
}
}
}
I need to save arrayRow[] and arrayCol[] in myArray[,].
For example,
if we have arrayRow[]={1,2,3} and arrayCol[]={4,5,6} then myArray[,]={(1,4),(2,5),(3,6)}
Note: arrayRow and arrayCol may have different lengths. In such cases the element that have no pair should be stored in the new single dimensional array result[].
Your arrayRow[] and arrayCol[] will be just two lines of a two-dimensional array (if you didn't mean jagged one).
So the code to unite two arrays into one is just:
public static T[,] Union<T>(T[] first, T[] second) //where T : struct
{
T[,] result = new T[2, Math.Max(first.Length, second.Length)];
int firstArrayLength = first.Length * Marshal.SizeOf(typeof(T));
Buffer.BlockCopy(first, 0, result, 0, firstArrayLength);
Buffer.BlockCopy(second, 0, result, firstArrayLength, second.Length * Marshal.SizeOf(typeof(T)));
return result;
}
As it have been mentinoned, BlockCopy is cooler than for cycle.
If you do mean that you need a jagged array (like int[][]), that the solutiona will be way more simplier:
public static T[][] UnionJagged<T>(T[] first, T[] second)
{
return new T[2][] { first, second };
}
Which transforms into even simplier if we add multiple-array-as-parameters functionality:
public static T[][] UnionJagged<T>(params T[][] arrays)
{
return arrays;
}
static void Main()
{
int[] a = new int[] { 10, 2, 3 };
int[] b = new int[] { -1, 2, -3 };
int[] c = new int[] { 1, -2, 3 };
int[][] jaggedThing = UnionJagged(a, b, c);
}
Didn't tryed this, and I'm just guessing what you want to acomplish, but here it is:
int[] arrayRow;
int[] arrayCol;
int[,] myArray = new int[Math.Max(arrayRow.Length, arrayCol.Length), 2];
for (int i = 0; i < arrayRow.Length; i++)
myArray[i, 0] = arrayRow[i];
for (int i = 0; i < arrayCol.Length; i++)
myArray[i, 1] = arrayCol[i];
More performant / another way:
public static void ConvertFlatArrayToMatrix(int[] array, int[,] matrix, int dimension) {
for(int i = 0; i < array.Length; i++) {
int r = Mathf.FloorToInt(i / dimension);
int c = i % dimension;
matrix[c,r] = array[i];
}
}
This will just push the result into a 2d array you pass in.
Keep in mind, I'm not checking length or protecting against anything here, this is just the concept and the bare minimum to get the job done.

matrix to array c#

Which would be the most efficient way to convert a squared matrix like
1 2 3
4 5 6
7 8 9
into
[1 2 3 4 5 6 7 8 9]
in c#
I was doing
int[,] array2D = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int[] array1D = new int[9];
int ci=0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
array1D[ci++] = array2D[i, j]);
}
}
LINQ makes this trivial.
int[,] array2d = ...;
var array1d = array2d.Cast<int>().ToArray();
Otherwise, your way is adequate but could be generalized:
int[,] array2d = ...;
var rows = array2d.GetLength(0);
var cols = array2d.GetLength(1);
var array1d = new int[rows * cols];
var current = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
array1d[current++] = array2d[i, j];
}
}
Or even:
int[,] array2d = ...;
var array1d = new int[array2d.GetLength(0) * array2d.GetLength(1)];
var current = 0;
foreach (var value in array2d)
{
array1d[current++] = value;
}
As Jeff said, LINQ makes this trivial. OfType<>() should generally be a little faster than Cast<> though:
array1D = array2D.OfType<int>().ToArray();
The implementation of OfType<> however will still suffer from boxing/unboxing penalties, as #phoog mentioned.
Just for the fun of it, if you want a fast LINQ-based solution (avoiding the cost of boxing) you could use this small extension method:
static class LinqEx
{
public static IEnumerable<T> Flatten<T>(this T[,] matrix)
{
foreach (var item in matrix) yield return item;
}
}
Or this, based on Jeff's 2nd solution:
public static IEnumerable<T> Flatten<T>(this T[,] matrix)
{
var rows = matrix.GetLength(0);
var cols = matrix.GetLength(1);
for (var i = 0; i < rows;i++ )
{
for (var j = 0; j < cols; j++ )
yield return matrix[i, j];
}
}
usage:
int[,] array2D = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int[] array1D = array2D.Flatten().ToArray();
I didn't fully profile this but I expect this will get you much better performance than the built-in options based on LINQ/IEnumerable. Jeff's second solution will however always be the fasted, it seems.
Alternate solution using Buffer.BlockCopy:
int[,] array2D = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int[] array1D = new int[ array2D.Length ];
Buffer.BlockCopy(array2D, 0, array1D, 0, array1D.Length * sizeof(int));
You're always better off allocating the complete result array in one hit, then copying the data in.
You should find the total size like this;
var size = arrays.Sum(a=> a.Length);
var result = new int[size];
And then copy the arrays using Array.CopyTo, instead of looping yourself;
var cursor = 0;
foreach(var a in arrays) {
a.CopyTo(result, cursor);
cursor += a.Length;
}
Array.CopyTo will be faster than your own loop; at least, not slower. It will probably use C's memcpy function internally to do a low-level block copy. This is as efficient as you can be.

Convert from List<double[]> to double[,]

Is there an one-liner (no looping) that converts List<double[]> to double[,]?
Converting to double[,] can only be done by looping through the list and requires that all arrays contained in the list are of same size:
double[,] arr = new double[list.Count, list[0].Length];
for (int i = 0; i < list.Count; i++)
{
for (int j = 0; j < list[0].Length; j++)
{
arr[i, j] = list[i][j];
}
}
Of course, you can easily create a jagged double[][] array of arrays by calling .ToArray():
double[] array = new double[] { 1.0, 2.0, 3.0 };
double[] array1 = new double[] { 4.0, 5.0, 6.0 };
List<double[]> list = new List<double[]>();
list.Add(array);
list.Add(array1);
double[][] jaggedArray = list.ToArray();
Well, you probably can't implement it without loops, but you can make the usage a one-liner :
double[,] array = list.To2DArray();
To2DArray is an extension method implemented as follows:
public static class ExtensionMethods
{
public static T[,] To2DArray<T>(this IEnumerable<IEnumerable<T>> source)
{
var jaggedArray = source.Select(r => r.ToArray()).ToArray();
int rows = jaggedArray.GetLength(0);
int columns = jaggedArray.Max(r => r.Length);
var array = new T[rows, columns];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < jaggedArray[i].Length; j++)
{
array[i, j] = jaggedArray[i][j];
}
}
return array;
}
}
Note that it will only work in C# 4, since earlier versions don't support covariance. This variant should work in C# 3 but it is more specific:
public static T[,] To2DArray<T>(this IEnumerable<T[]> source)
{
var jaggedArray = source.ToArray();
// same code from here
}
If a 2 dim array is to be created from List of 1 dim array then looping is required, though it may not look like that at the call-site.
public static T[,] ToMultidimensional<T>(this T[][] arr, int maxSize)
{
T[,] md = (T[,])Array.CreateInstance(typeof(double), arr.Length, maxSize);
for (int i = 0; i < arr.Length; i++)
for (int j = 0; j < arr[i].Length; j++)
md[i, j] = arr[i][j];
return md;
}
var arr = new List<double[]>
{
new double[] { 1, 2, 3 },
new double[] { 4, 5 }
}
.ToArray();
var j = arr.ToMultidimensional(arr.Max(a => a.Length));
This syntax should work:
return new List{new double[] { minX, minY }, new double[] { maxX, maxY }};

Categories