How do I convert a multi-dimensional array of int into a multi-dimensional dictionary using Lambda?
For example I would like to convert Test1 (int[2,3]) into Test 3 (Dictionary<(int,int),int>)
int[,] Test1 = new int[2, 3];
int k = 0;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
Test1[i, j] = k++;
}
}
I can easily convert it into dictionary using the traditional way with the "for - next" loop but when I tried using lambda:
Dictionary<(int,int),int>Test3 = Enumerable.Range(0, Test1.Length)
.ToDictionary((int i ,int j )=>new { z =Test1[i, j] });
I got the syntax error below:
Error CS0411 The type arguments for method 'Enumerable.ToDictionary<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
How do I specify the type arguments explicitly?
Unfortunately you can't easily use Linq to loop through "rows" of a 2-D array, since the iterator for a square array just loops through the elements. You'll need to use an old-fashion for loop:
var Test3 = new Dictionary<(int,int),int>();
for (int i = 0; i < Test1.GetLength(0); i++)
{
Test3[(Test1[i, 0], Test1[i, 1])] = Test1[i, 2];
}
This assumes that the pairs in the first two "columns" are unique, otherwise the last one would "win".
You could use Linq to enumerate through the rows by usinng Range over one axis as you tried to do:
Dictionary<(int,int),int>Test3 = Enumerable
.Range(0, Test1.GetLength(0))
.ToDictionary(i => (Test1[i, 0], Test1[i, 1]), i => Test1[i, 2]);
Note that the lambdas in ToDictionary define the key and value, respectively.
but the for loop is cleaner and easier to understand in my opinion.
Related
I want to do something like this.
The array itself needs to be a single dimensional array but it's elements must hold different multidimensional arrays
Looks like you want something like this:
int[][,] array = new[]
{
new int[2, 2],
new int[3, 3],
new int[4, 4]
};
foreach (var table in array)
{
for (int j = 0; j < table.GetLength(1); j++)
for (int i = 0; i < table.GetLength(0); i++)
table[i, j] = i * j; // feed in some value
}
Documentation (loop up jaggedArray4 example).
You could consider not working with raw arrays, but encapsulate the matrices into a separate class. This way your code will be more readable.
Using Math.Net Numerics, how can I index parts of a matrix?
For example, I have a collection of ints and I want to get a submatrix with the rows and columns chosen accordingly.
A[2:3,2:3] should give me that 2 x 2 submatrix of A where the row index and the column index is either 2 or 3
Just use some thing like
var m = Matrix<double>.Build.Dense(6,4,(i,j) => 10*i + j);
m.Column(2); // [2,12,22,32,42,52]
to access the desired column use the Vector<double> Column(int columnIndex) extension method.
I suspect you were looking for something like this Extension method.
public static Matrix<double> Sub(this Matrix<double> m, int[] rows, int[] columns)
{
var output = Matrix<double>.Build.Dense(rows.Length, columns.Length);
for (int i = 0; i < rows.Length; i++)
{
for (int j = 0; j < columns.Length; j++)
{
output[i,j] = m[rows[i],columns[j]];
}
}
return output;
}
I've omitted the exception handling to ensure rows and columns are not null.
i have array that call nums, it contain int var.
the array is 2d -
int[,] nums = new int[lines, row];
i need to print each line in the array in other line.
when i try to print to array like this:
for (int i = 0; i < lines; i++)
for (int j = 0; j < 46; j++)
Console.Write(nums[i,j]);
** when i using the above syntax i dont get an error in visual studio, but when i run the program, i got error in this line - Console.Write(nums[i,j]);.
error - system.IndeOutOfRangeException.
i got the error , i try to change the syntax to this:
for (int i = 0; i < lines; i++)
for (int j = 0; j < 46; j++)
Console.Write(nums[i][j]);
the error: "wrong number of indices inside []; expected 2"
and:
for (int i = 0; i < lines; i++)
for (int j = 0; j < 46; j++)
Console.Write(nums[i][j].tostring());
update
i am so stupid... i write 46(number in my program) instead of 6(numbers in each row) thats whey is was out of range.
ty for all, and i am sry to open a question with such bad problem...
TY!
If lines and row are positive integer values, say, int lines = 5; int row = 7; you can print out your table like this:
int[,] nums = new int[lines, row]; // <- Multidimensional (2 in this case) array, not an array of array which is nums[][]
//TODO: fill nums with values, otherwise nums will be all zeros
for (int i = 0; i < lines; i++) {
Console.WriteLine(); // <- let's start each array's line with a new line
for (int j = 0; j < row; j++) { // <- What the magic number "46" is? "row" should be here...
Console.Write(nums[i, j]); // <- nums[i, j].ToString() doesn't spoil the output
if (j > 0) // <- let's separate values by spaces "1 2 3 4" instead of "1234"
Console.Write(" ");
}
}
You are dealing with 2 different types of arrays
int[,] nums = new int[lines, row];
is a Multi-Dimensional Array. Elements of the array can be accessed using nums[x,y].
When you use nums[x][y] you are dealing with an array of arrays.
You cannot use array of arrays syntax with a multi-dimensional array.
You might try What are the differences between Multidimensional array and Array of Arrays in C#? for details.
I am confused in comparing arrays
my code is:
result is a 1D array and symboltable1 is a 2D array... these arrays contain at least 100, 100 values
for (int row = 0; row < symboltable1.GetLength(0); row++)
{
for (int column = 0; column < symboltable1.GetLength(1); column++)
{
for (int we = 0; we < result.Length; we++)
if (result[we].Contains(symboltable1[row, column]))
listBox1.Items.Add("vliad");
else
listBox2.Items.Add("invalid");
}
}
what I want now is how to store valid terms in another 2D array named symboltable2?
by valid terms, i mean the terms which are in both of the above said arrays????
You can use the generic function below to flatten a 2D array into an IEnumerable, put elements into a hash set, and check the terms against that hash table.
private static IEnumerable<T> Flatten<T>(T[,] data) {
var r = data.GetLength(0);
var c = data.GetLength(1);
return Enumerable.Range(0, r*c).Select(i => data[i/c, i%c]);
}
var symTableItems = new HashSet<string>(Flatten(symboltable1));
var allValid = result.Where(s => symTableItems.Contains(s)).ToList();
I am making a program that stores data in a 2D array. I would like to be able to delete rows from this array. I cannot figure out why this code doesn't work:
for (int n = index; n < a.GetUpperBound(1); ++n)
{
for (int i = 0; i < a.GetUpperBound(0); ++i)
{
a[i, n] = a[i, n + 1];
}
}
Could someone please help me out? I would like it to delete a single row and shuffle all the rows below it up one place. Thankyou!
you need to create a new array if you want to delete an item
try something like this
var arrayUpdated = new string[a.GetUpperBound(1)][a.GetUpperBound(0)-1];
for (int n = index; n < a.GetUpperBound(1); n++)
{
for (int i = 0; i < a.GetUpperBound(0); i++)
{
arrayUpdated [i, n] = a[i, 1];
}
}
The nested for loop method here works well: https://stackoverflow.com/a/8000574
Here's a method that converts the outer loop of the [,] array method above to use linq. Using linq here is only recommended if you are also doing other things with linq during the traversal.
public T[,] RemoveRow<T>(T[,] array2d, int rowToRemove)
{
var resultAsList = Enumerable
.Range(0, array2d.GetLength(0)) // select all the rows available
.Where(i => i != rowToRemove) // except for the one we don't want
.Select(i => // select the results as a string[]
{
T[] row = new T[array2d.GetLength(1)];
for (int column = 0; column < array2d.GetLength(1); column++)
{
row[column] = array2d[i, column];
}
return row;
}).ToList();
// convert List<string[]> to string[,].
return CreateRectangularArray(resultAsList); // CreateRectangularArray() can be copied from https://stackoverflow.com/a/9775057
}
used Enumerable.Range to iterate all rows as done in https://stackoverflow.com/a/18673845
Shouldn't ++i be i++? ++i increments before matrix operation is performed(ie pre-increment)