Not sure if this is the best way to do this but I've created a 2D array from values in an excel file that i want to use as variables within my application that control where to look for things like file paths and files.
The array is built and all data from the file is contained within it:
for (int i = 0; i <= bindingSourceConfig.Count - 1; i++) // for each row in the binding source data
{
for (int j = 0; j <= 2 - 1; j++) // for each column, only need one and 2
{
System_Var_Array[i, j] = (bindingSourceConfig.DataSource as DataTable).Rows[i][j].ToString();
}
}
Now i want to be able to look in the array for my variable say "Project_Directory" and have it return "C:\Users\User\Dropbox\default\master\support"
Is this even possible?
EDIT 1:
Purpose of doing it this way is to make an easily customizable/configurable multi project environment where by anyone can simply edit the paths in the excel file and import that file into the application.
I can not in my incompetence see a way of setting these 'variables' at a class level without first extracting the 'variable' and the 'value' from the excel data.
Is there a simple way of looking up the 'variable' in bindingSource?
EDIT 2:
debugger image
var name = "Project_Directory";
string value = null;
for (int i = 0; i<System_Var_Array.GetLength(0); i++) {
if (System_Var_Array[i,0]==name) {
value = System_Var_Array[i,1];
break;
}
}
After the loop stop, value will contain the data you need, assuming it exists (otherwise it will be null. A far simpler approach will be using Dictionary<string,string>, if you generate it with
var systemVars = new Dictionary<string,string>();
var dt = bindingSourceConfig.DataSource as DataTable;
for (int i = 0; i < bindingSourceConfig.Count; i++) // for each row in the binding source data
{
systemVars[dt.Rows[i][0].ToString()] = dt.Rows[i][1].ToString();
}
then to get the value for "Project_Directory", simply call
var value = systemVars["Project_Directory"];
You should use an appsettings file for this instead, it's the dotnet standard solution for this sort of thing. Please see https://learn.microsoft.com/en-us/dotnet/core/extensions/configuration.
Related
i am trying to use C# xll to make a set of functions for excel. In one function i need to pass range as argument to the function. For eg. say sum of all cells in a range. how to achieve it
The best way to interact with Excel from C# is to use ExcelDNA. If you're using a "C# XLL" then there's a decent chance you ae already using it! Then you need to decide if you want to work with a Range or array (it's the same distinction when writing functions in VBA). If you just want to read values from the sheet, you probably want an array, in which case something like this will work (assuming you've set up ExcelDNA correctly):
public static double SumFunc(double[,] values)
{
int rows = values.GetLength(0);
int cols = values.GetLength(1);
double total = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
total += values[i, j];
}
}
return total ;
}
Note this will give a #VALUE! error if any of the passed values are not numbers. If you want to use a true Range (actually an ExcelReference in ExcelDNA), you can follow the answers here and here.
My program has to place objects on a map, i have to get the informations about the objects from a text file but my problem is that there is no limit in objects so when i write my code i don't know if someone wants to place 1 or 10 or 5 objects. Every object has a separate line where you can give the parameters for example x,y coordinates on the map to place etc etc.
I figured out that i will ask the user to write in a line before the objects the number of objects he wants to add.Here is my example :
txt file:
200<----not important here
10000<----not important here
5<---number of objects
2,5/60-60<--object
4,5/70-70<--object
5,5/80-80<--object
1,1/30-30<--object
10,10/100-100<--object
10,1/5<----not important here
height,weight/x-y
And vs throws out of range exception. Hope u understood my english and my problem
int numberofObjects = int.Parse(data[2]);
Targets[] TargetsGet = new Target[numberofObjects];
int j = 0;
for (int i = 4; i <= numberofObjects+3; i++)
{
targets[j] = new Target(int.Parse(data[i].Split(',')[0]), int.Parse(data[i].Split('/')[0].Split(',')[1]), new Coordinate(int.Parse(data[i].Split('/')[1].Split('-')[0]),int.Parse( data[i].Split('-')[1])));
j++;
}
return TargetsGet;
}
First of all, your solution works.
If you don't want to ask the user to specify the number of objects, you can use a list instead of an array and use a separator at the end of the object list. For example:
List<Targets> TargetsGet = new List<Target>();
int j = 0;
while(data[j]!="separator")
{
targets.Add(new Target(int.Parse(data[j].Split(',')[0]), int.Parse(data[j].Split('/')[0].Split(',')[1]), new Coordinate(int.Parse(data[j].Split('/')[1].Split('-')[0]),int.Parse( data[j].Split('-')[1])));
j++;
}
return TargetsGet.ToArray();
}
The file should be modified so the string "separator" will be after the object list:, for example:
200<----not important here
10000<----not important here
2,5/60-60<--object
4,5/70-70<--object
5,5/80-80<--object
1,1/30-30<--object
10,10/100-100<--object
separator
10,1/5<----not important here
height,weight/x-y
Im developing a small app/game in Unity3D.
The problem is:
I need to clone an array (call it tempArray) and make some modifications to it. Then i need to change values of the MAIN array to modified tempArray. However, whenever i make changes to cloned array, the same changes are made to the main one.
So i used the following code:
private Cell[,] allCells = new Cell[256, 256];
private Cell[,] cellClone = new Cell[256,256];
//meanwhile initiated to some values//
//Here i clone the array.
cellClone = (Cell[,])allCells.Clone();
//Here i output the values for an element from both arrays.
Debug.Log(cellClone[0, 0].region.name.ToString());
Debug.Log(allCells[0, 0].region.name.ToString());
//Here i want to change "Region" variable of cellClone ONLY.
cellClone[0, 0].setRegion(new Region("testregion123", Color.cyan, false));
//Finally, i output the same values again. Only cellClone should change.
Debug.Log(cellClone[0, 0].region.name.ToString());
Debug.Log(allCells[0, 0].region.name.ToString());
However, the output shows that allCells[0,0] element was also changed. This means that any operation I do to the cloned array, is executed to the main array.
EDIT:
After alot of playing around I implemented this as a solution. Im posting this in case anybody has a similar problem.
But Im not sure if this is how its supposed to be done so if anybody has any information - Ill be checking this post.
for (int i = 0; i < allCells.GetLength(0); i++)
{
for (int j = 0; j < allCells.GetLength(1); j++)
{
//cellClone[i, j] = allCells[i, j].Clone();
//cellClone[i, j] = new Cell((int)allCells[i, j].position.x, (int)allCells[i, j].position.y, allCells[i, j].getRegionName());
cellClone[i, j] = allCells[i, j].clone();
}
}
And the clone function:
public Cell clone()
{
Cell n = new Cell((int)position.x, (int)position.y, regionName);
return n;
}
However, the output shows that allCells[0,0] element was also changed. This means that any operation I do to the cloned array, is executed to the main array.
Unless Cell is a struct, your setRegion method (which sounds like it should really just be a Region property) isn't changing the contents of the array at all. It's changing the data stored in the object that both arrays contain a reference to.
You're performing a shallow clone of the array, which means the references are being copied - but each Cell object is not being cloned. (We don't even know whether that operation has been implemented within Cell.)
It sounds like you want to perform a deep clone, something like:
for (int i = 0; i < allCells.GetLength(0); i++)
{
for (int j = 0; j < allCells.GetLength(1); j++)
{
cellClone[i, j] = allCells[i, j].Clone();
}
}
... where you'd need to implement the Clone method yourself. (It may need to clone the region in turn, for example.)
Check this out:
Array.Copy
Array.Copy (Array, Array, Int32)
Easier and only 1 line of code;
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.
I'm currently coding a project that can take up to 200 entries of a specific product, as determined by user input. Basically, my GUI loads, and I use jQuery to dynamically build the entries whenever there is a change to the amount field. When using jQuery, I simply give each of them ids in the form of variable1, variable2, ...., variableX (where X is the amount of entries indicated). Small snippet of code to clarify:
for(var i = 1;i <= amount_selected; i++) {
$('table_name tr:last').after('<tr><td><input type="text" id="variable' + i + '"></td></tr>');
}
Now when I try to move to the back end, I'm trying to reference these variable names by putting them in a list. I went ahead and put them in a list of HtmlInputText, to call the Variable names from the list itself. (This would save having to call all (up to 200) methods manually, which is really not an option).
So what I did (in C#) was:
List<HtmlInputText> listvar = new List<HtmlInputText>();
for(int i = 1; i <= amount_selected; i++) {
string j = "variable" + Convert.ToString(i);
HtmlInputText x = j;
listvar.Add((x));
samplemethod(listvar[i]);
}
But it's not working at all. Does anyone have any ideas as to how this would be done, without doing so manually? I know my logic might be completely off, but hopefully this illustrates at least what I'm attempting to do.
I'm assuming these inputs are in a form? If you're submitting then you can access the text boxes from the Request object:
List<string> results = new List<string>();
for (int i = 1; i <= amount_selected; i++)
{
string s = String.Format("{0}", Request.Form["variable" + Convert.ToString(i)]);
results.Add(s);
}
you could do $("#variable" + Convert.ToString(i)).val()