C# - can you name a matrix with the contents of a string - c#

Basically I have x amount of matrices I need to establish of y by y size. I was hoping to name the matrices: matrixnumber1 matrixnumber2..matrixnumbern
I cannot use an array as its matrices I have to form.
Is it possible to use a string to name a string (or a matrix in this case)?
Thank you in advance for any help on this!
for (int i = 1; i <= numberofmatricesrequired; i++)
{
string number = Convert.ToString(i);
Matrix (matrixnumber+number) = new Matrix(matrixsize, matrixsize);
}

You can achieve a similar effect by creating an array of Matrices and storing each Matrix in there.
For example:
Matrix[] matrices = new Matrix[numberofmatricesrequired];
for (int i = 0; i < numberofmatricesrequired; i++)
{
matrices[i] = new Matrix(matrixsize, matrixsize);
}
This will store a bunch of uniques matrices in the array.

If you really want to you could create a Dictionary<String, Matrix> to hold the matrices you create. The string is the name - created however you like.
You can then retrieve the matrix by using dict["matrix1"] (or whatever you've called it).
However an array if you have a predetermined number would be far simpler and you can refer to which ever you want via it's index:
Matrix theOne = matrix[index];
If you have a variable number a List<Matrix> would be simpler and if you always added to the end you could still refer to individual ones by its index.

I'm curious why you cannot use an array or a List, as it seems like either of those are exactly what you need.
Matrix[] matrices = new Matrix[numberofmatricesrequired];
for (int i = 0; i < matrices.Length; i++)
{
matrices[i] = new Matrix(matrixsize, matrixsize);
}
If you really want to use a string, then you could use a Dictionary<string, Matrix>, but given your naming scheme it seems like an index-based mechanism (ie. array or List) is better suited. Nonetheless, in the spirit of being comprehensive...
Dictionary<string, Matrix> matrices = new Dictionary<string, Matrix>();
for (int i = 1; i <= numberofmatricesrequired; i++)
{
matrices.Add("Matrix" + i.ToString(), new Matrix(matrixsize, matrixsize));
}

Related

How can I assign different iteration within for loop in C#?

I have list called “images” which is contained of the series of bitmap images.
My question is how can I loop through every single element of my “images” list and do this operation for different elements of my list “images”?
You want to keep collections for each element of images, right?
You'll need to maintain a list of lists, or something similar:
List<List<int>> stuffOfImages = new List<List<int>>();
for (int x = 0; x < images[i].Width; x++) {
var stuffOfImage = new List<int>();
stuffOfImages.Add(stuffOfImage);
for (int y = 0; y < images[i].Height; y++) {
}
}
Note that you lose all reference to the associated image - it might be worthy creating a type so you can keep a reference to the image and the integer collection associated with it in one place and related.
I'm a little unclear as to what you mean, so please elaborate if necessary.

This seems like a bug in studio or compilator

Problem is that after Randomize func, array forcombo equals random_for_combo, but I do not equate them anywhere. Please help.
private void button1_Click(object sender, EventArgs e)
{
string sub = "1#2#3#4#5#6#7#8#9#10";
string[] split = sub.Split('#');
string[] forcombo = new string[split.Length / 2];
int s = 0;
for (int j = 1; j <= split.Length - 1; j += 2)
{
forcombo[s] = split[j];
s++;
}
string[] random_for_combo = new string[forcombo.Length];
random_for_combo = forcombo;
MessageBox.Show(forcombo[0] + forcombo[1] + forcombo[2] + forcombo[3] + forcombo[4], "Before random");
random_for_combo = RandomizeStrings(random_for_combo);
MessageBox.Show(forcombo[0]+forcombo[1]+forcombo[2]+forcombo[3]+forcombo[4], "After random");
}
public static string[] RandomizeStrings(string[] arr)
{
ArrayList l1 = new ArrayList(arr.Length);
ArrayList l2 = new ArrayList(arr.Length);
foreach (object k in arr)
{
l1.Add(k.ToString());
}
while (l1.Count > 0)
{
Random rnd = new Random();
int rand = rnd.Next(l1.Count);
l2.Add(l1[rand]);
l1.RemoveAt(rand);
Thread.Sleep(rnd.Next(50));
}
for (int i = 0; i < l2.Count; i++)
{
arr[i] = l2[i].ToString();
}
return arr;
}
Some helpless info to complete question..
There's a couple of problems with this code:
You're copying the reference from one array variable into another:
random_for_combo = forcombo;
This does not make the two variables contain two arrays that contain the same values, the two values now refer to the same one array in memory. Change one, and it will appear the other one changed as well. Think of the two variables as postit notes with the address of a house on them, the same address. If you go to the house and rearrange the furniture, "both houses" will appear to be changed. There is only one house however.
When you pass the array to the randomize method, you're passing a reference to the array, not a copy of the array, which means that if you change the contents of the array, you're not working on a copy, you're working on the original. This means that the array you get passed, and the array you return, is the same one array in memory
Probably not the source of the bugs in your question, but you shouldn't construct new Random objects every time you use it in a loop, instead construct it once and reuse, otherwise you risk getting back just a few distinct values.
Lastly, if your gut reaction is "this is a bug in visual studio or C#", then it almost never is, always work on the presumption that it is your own code that is faulty. By "almost never" I would say that the chance of you hitting a bug in C# or Visual Studio by chance is none.
To make a new array with the same contents of another, you have a few options:
Explicitly make an array and copy over the elements one by one:
random_for_combo = new string[forcombo.Length];
for (int i = 0; i < forcombo.Length; i++)
random_for_combo[i] = forcombo[i];
Use Array.Copy instead of the for-loop:
random_for_combo = new string[forcombo.Length];
Array.Copy(forcombo, random_for_combo, forcombo.Length);
Use the new Linq ToArray extension method:
random_for_combo = forcombo.ToArray();
Note that even though this looks like a no-op (since forcombo is an array), you'll actually get a new array with the same contents.
but you did here :
random_for_combo = forcombo;
you set random_for_combo so it point to forcombo.
if you want to use the original array than you need to copy it to new array
something like this (instead of the above line)
string[] random_for_combo = new string[forcombo.Length];
for (int i = 0; i < forcombo.Length; i++)
{
random_for_combo[i] = forcombo[i];
}

How can I make a 2D array from this one-line, comma delimited file?

I am trying to figure out how to turn the following, one-line CSV file into a 30x30 2D array.
http://pastebin.com/8NP7s7N0
I've tried looking it up myself, but I just can't seem to wrap my brain around the concept of multidimensional arrays, and I don't know how to turn a one-line file like this into an array of a specified size.
I want to be able to make an array that would look like this when printed:
0,0 = 2
0,1 = 2
All the way to 30,30.
Most of the numbers in the CSV are indeed 2's, but some are 1s. The difference is very important though. I am trying to make collision detection for a game, and this CSV file is the map. All I need left is how to create this array - leave the rest to me. :)
Thank you very much to all, have a nice day.
This should be a complete example using a 5 x 5 grid. I've tried it and seems to work as expected:
namespace ConsoleApplication1
{
using System;
class Program
{
const int MapRows = 5;
const int MapColumns = 5;
static void Main(string[] args)
{
// Create map and the raw data (from file)
var map = new int[MapRows, MapColumns];
string rawMapData = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25";
string[] splitData = rawMapData.Split(',');
int index = 0;
// Loop through data
for (int row = 0; row < MapRows; row++)
{
for (int column = 0; column < MapColumns; column++)
{
// Store in map and show some debug
map[row, column] = int.Parse(splitData[index++]);
Console.WriteLine(string.Format("{0},{1} = {2}", row, column, map[row, column]));
}
}
// Wait for user to read
Console.ReadKey();
}
}
}
Assuming your file is 900 elements first you need to read it in..
something along the lines of
line = myStreamReader.readLine().Split(',').. then in John U's example, value would be the next index in this array called line
I'll let you work out whats missing from my example :P
well, first you need to get the numbers...
var numbers = Read_File_As_String().Split(new char[',']).Select(n => int.Parse(n)).ToList();
then, you need to build your array
const int ROWS = 30;
const int COLS = 30;
var result = new int[ROWS, COLS];
for (int row = 0; row < ROWS; row++)
for (int col = 0; col < COLS; col++)
result[row, col] = numbers[(row * COLS) + col];
for(row=0;row<30;row++)
{
for(col=0;col<30;col++)
{
array[row][col] = value;
}
}
Value would need to be moved along to point to the next thing each time, but I'm sure you can figure that out.
Edited to add: If it's a map it might be easier to store it as an array in the first place.
Since you asked about the concept of multi-dimensional arrays, here are some useful ways of thinking about arrays. Please note these are analogies, meant to help you visualize them.
Think of a 1D array as a list of items (not in the programming sense of list!).
Think of a 2D array as a table (again, not in the programming sense!). In a table (like a spreadsheet) you have rows and columns, and each dimension in your array accesses one of these.
For higher dimensional arrays, it may help to think geometrically. For instance, you can think of 3D arrays as 3-dimensional points in space, and 4D arrays as 4-dimensional points in space-time.
So if you have a single CSV file, start off by conceptualizing how this would be re-structured as a table. Once you have that, you have a pretty straight-forward mapping to the array.

C# rows of multi-dimensional arrays

In the C# programming language, how do I pass a row of a multi-dimensional array? For example, suppose I have the following:
int[,] foo;
foo = new int[6,4];
int[] least;
least = new int[6];
for(int i = 0; i < 6; i++)
{
least[i] = FindLeast(ref foo[i]); //How do I pass the ith row of foo???
}
Also, could anyone explain to me the benefit of having rectangular and jagged arrays in C#? Does this occur in other popular programming languages? (Java?)
Thanks for all the help!
You can't pass a row of a rectangular array, you have to use a jagged array (an array of arrays):
int[][] foo = new int[6][];
for(int i = 0; i < 6; i++)
foo[i] = new int[4];
int[] least = new int[6];
for(int i = 0; i < 6; i++)
least[i] = FindLeast(foo[i]);
EDIT
If you find it so annoying to use a jagged array and desperately need a rectangular one, a simple trick will save you:
int FindLeast(int[,] rectangularArray, int row)
You don't, with a rectangular array like that. It's a single object.
Instead, you'd need to use a jagged array, like this:
// Note: new int[6][4] will not compile
int[][] foo = new int[6][];
for (int i = 0; i < foo.Length; i++) {
foo[i] = new int[4];
}
Then you can pass each "sub"-array:
int[] least = new int[foo.Length];
for(int i = 0; i < 6; i++)
{
least[i] = FindLeast(foo[i]);
}
Note that there's no need to pass foo[i] by reference1, and also it's a good idea to assign local variables values at the point of declaration, when you can. (It makes your code more compact and simpler to understand.)
1 If you're not sure about this, you might want to read my article on parameter passing in C#.
Update: As Jon Skeet rightly points out, this does not provide a reference to the row, but rather creates a new copy. If your code needs to change a row, this method doesn't work. I have renamed the method to make this clear.
Update 2: If you want to be able to edit the fields, and have the changes happen to the parent array, too, you can use the wrapper I provide in this library I maed. The resulting row foo.Row(i) is not an array, but instead implements IList, so if you need to pass an array this is not a solution, either.
This extension method will allow you to query a multi-dimensional array for rows. It should be noted that this is computationally heavy (not efficient) and if it is possible you should use a jagged array for these situations. If, however, you find yourself in a situation where you cannot use a jagged array, this might be useful.
public static T[] CopyRow<T>(this T[,] arr, int row)
{
if (row > arr.GetLength(0))
throw new ArgumentOutOfRangeException("No such row in array.", "row");
var result = new T[arr.GetLength(1)];
for (int i = 0; i < result.Length; i++)
{
result[i] = arr[row, i];
}
return result;
}
Your code can now be rewritten:
int[,] foo;
foo = new int[6,4];
int[] least;
least = new int[6];
for(int i = 0; i < 6; i++)
{
least[i] = FindLeast(ref foo.CopyRow(i));
}

How to have Column, Rows array (not vice versa)

Making game of life I need to a have a grid that is 30x20 (X * Y). The problem is (I had another question regarding to that) that the c# arrays are rows, columns. So when I use CursorPosition() to drawing I need to swap it because it wants column at first.
Is there any way how I can reverse it so I can use like this?
int [,] Array = new int[30,20];
Console.SetCursorPosition(29,19) // now its vice versa, I would need to use 19,29.
I believe that this is purely conceptual (c# arrays are neither row/col or col/row that is up to the developer) and comes down to iterating your array in either a depth-first or breadth-first manner e.g.
//Breadth-first
for(int x = 0; x < col.Length; x++)
{
for(int y = 0; y < row.Length; y++)
{
}
}
//Depth-first
for(int y = 0; y < row.Length; y++)
{
for(int x = 0; x < col.Length; x++)
{
}
}
At first I was inclined to answer no as the parameters to Console.SetCursorPosition is Positional parameters. But when I remember that C# have Named parameters too so something like this works.
int a = 10;
int b = 20;
Console.SetCursorPosition(top: a, left: b);
This is the closest you can get, if you want to know why, search for the terms above
What you need is a data structure to store date in relation with an x,y coordinate.
You do not have to use a multi-dimensional array for this. You could very easily create a class that hides the specific implementation from the other classes.
In fact this will make your design more robust.
You can store the data in a database, bitarray, single dimension array, etc.

Categories