Load board from string and store in two dimensional array - c#

I'm trying to store a board made up of 1's and 0's in a two-dimensional array. I'm trying to return 3 sets of 3 values into the array but it says a value is expected in csvArray[][].
I've already created a string of 1's and 0's and split them into substrings separated by "\n"
int[][] loadBoardfromString(string Data)
{
string csvBoard = "0,1,0\n2,0,1\n0,0,1";
string[] csvArray = csvBoard.Split('\n');
return csvArray[][];
}

Here's what you need:
string csvBoard = "0,1,0\n2,0,1\n0,0,1";
int[][] csvArray =
csvBoard
.Split('\n') // { "0,1,0", "2,0,1", "0,0,1" }
.Select(x =>
x
.Split(',') // { "X", "Y", "Z" }
.Select(y => int.Parse(y)) // { X, Y, Z }
.ToArray())
.ToArray();

My guess this is some sort of homework so I will try use the most basic solution so the teacher doesn't know :).
string csvBoard = "0,1,0\n2,0,1\n0,0,1";
// This splits the csv text into rows and each is a string
string[] rows = csvBoard.Split('\n');
// Need to alocate a array of the same size as your csv table
int[,] table = new int[3, 3];
// It will go over each row
for (int i = 0; i < rows.Length; i++)
{
// This will split the row on , and you will get string of columns
string[] columns = rows[i].Split(',');
for (int j = 0; j < columns.Length; j++)
{
//all is left is to set the value to it's location since the column contains string need to parse the values to integers
table[i, j] = int.Parse(columns[j]);
}
}
// For jagged array and some linq
var tableJagged = csvBoard.Split('\n')
.Select(row => row.Split(',')
.Select(column => int.Parse(column))
.ToArray())
.ToArray();
Here is my suggestion on how you should improve this so you learn the concepts. Make a more applicable method that can spilt any random csv no matter the size and return a two dimensional array not a jagged array. Also try to handle the case when someone doesn't put a valid csv text as a parametar into your method.

Related

Reading CSV of unknown number of rows/columns into Unity array

I want a 2D array generated from a CSV file with unknown number of rows/columns. The column count is fixed based on the header data. I need to be able to process it as a grid going both across rows and down columns hence needing array.
At the moment, I can split the data into rows, then split each row into components. I then add each row to a list. This all seems to work fine.
What I cant do is convert a list of string arrays into a 2d array.
It currently is failing on the line string[,] newCSV = csvFile.ToArray(); with error Cannot implicitly convert type 'string[][]' to 'string[ * , * ]' so I'm obviously not declaring something properly - I've just no idea what!
List<string[]> csvFile = new List<string[]>();
void Start()
{
// TODO: file picker
TextAsset sourceData = Resources.Load<TextAsset>("CSVData");
if (sourceData != null)
{
// Each piece of data in a CSV has a newline at the end
// Split the base data into an array each time the newline char is found
string[] data = sourceData.text.Split(new char[] {'\n'} );
for (int i = 0; i < data.Length; i ++)
{
string[] row = data[i].Split(new char[] {','} );
Debug.Log(row[0] + " " + row[1]);
csvFile.Add(row);
}
string[,] newCSV = csvFile.ToArray();
} else {
Debug.Log("Can't open source file");
}
Since your data is in the form of a table, I highly suggest using a DataTable instead of a 2d array like you're currently using to model/hold the data from your csv.
There's a ton of pre baked functionality that comes with this data structure that will make working with your data much easier.
If you take this route, you could then also use this which will copy CSV data into a DataTable using the structure of your CSV data to create the DataTable.
It's very easy to configure and use.
Just a small tip, you should always try to use data structures that best fit your task, whenever possible. Think of the data structures and algorithms you use as tools used to build a house, while you could certainly use a screw driver to pound in a nail, it's much easier and more efficient to use a hammer.
You can use this function to get 2d array.
static public string[,] SplitCsvGrid(string csvText)
{
string[] lines = csvText.Split("\n"[0]);
// finds the max width of row
int width = 0;
for (int i = 0; i < lines.Length; i++)
{
string[] row = SplitCsvLine(lines[i]);
width = Mathf.Max(width, row.Length);
}
// creates new 2D string grid to output to
string[,] outputGrid = new string[width + 1, lines.Length + 1];
for (int y = 0; y < lines.Length; y++)
{
string[] row = SplitCsvLine(lines[y]);
for (int x = 0; x < row.Length; x++)
{
outputGrid[x, y] = row[x];
// This line was to replace "" with " in my output.
// Include or edit it as you wish.
outputGrid[x, y] = outputGrid[x, y].Replace("\"\"", "\"");
}
}
return outputGrid;
}

Convert string[] to int

I have an array of integers in string form.
string [] TriangleSideLengths
In this array there is going to be 3 int values which represent side length of a triangle. Is there a way from which I can extract individual all 3 values from my array TriangleSideLengths into three int objects like int intSideLengthOne,intSideLengthTwo and intSideLengthThree.
I want to be able to test if these three values actually form a valid triangle?
For instance, entering lengths 10, 10, 100000 wouldn't make it a valid isosceles triangle.
I wanna be able to do this check with the three values stored in my array TriangleSideLengths.
a + b > c
a + c > b
b + c > a
Any help is greatly appreciated.
Thanks a lot!! :)
You can use LINQ to parse the numbers from the string, like this:
var threeSides = TriangleSideLengths.Select(int.Parse).ToArray();
Here is a demo on ideone.
To do the check, sort the numbers in ascending order, then check that the sum of the first two is strictly greater than the third one:
Array.Sort(threeSides);
if (threeSides[0]+threeSides[1] > threeSides[2]) {
...
}
Note that it is not a sufficient condition for the numbers to define a triangle: you must also check that the numbers are strictly positive.
Try this
string [] TriangleSideLengths = new string[3];
int[] lengths = new int[3];
for(int i = 0; i<=2;i++)
{
lengths[i]=Convert.ToInt32(TriangleSideLengths[i]);
}
if(lengths[0]+lengths[1]>lengths[2])
//go crazy
string[] TriangleSideLengths = { "10", "20", "300"};
int[] sides = new int[TriangleSideLengths.Length];
for (int i = 0; i < TriangleSideLengths.Length; i++)
{
sides[i] = int.Parse(TriangleSideLengths[i]);
}
int[] sides = new int[TriangleSideLengths.Length];
int counter=0;
foreach(var str in TriangleSideLengths)
{
int.TryParse(str, out sides[counter++]);
}
if(sides[0] + sides[1] > sides[2]){...}
public int toInt(string text)
{
int tonumber = int.Parse(text);
return tonumber;
}

List of numbers to 2d int array

I have a list of numbers on a textbox like so (the numbers used are just examples):
1 1 1
2 2 2
...
So I want to convert that into a 2d array. I know to use .ToArray() or Regex.Split() for 1d lists but am not sure how to use that for 2d. I've also tried to use those functions on a string[] array to make it 2d but there was an error.
Also, the array is supposed to be an int[,] so that the values in the array can be compared. Any help would be appreciated, thanks!
Here you go, if you don't understand any part please ask in the comments:
// assuming the numbers are in perfect 2D format in textBox (only 1 newline separates the lines, only 1 space separates numbers in each line and all lines have the same amount of numbers)
string textWithNumbers = textBox.Text;
// first put all lines into an string array
string[] allLines = textWithNumbers.Split(new string[]{Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
// calculate 2D array's dimension lengths, and initialize the 2Darray
int rowCount = allLines.Length;
int columnCount = ((allLines[0].Length + 1) / 2);
int[,] twoDArray = new int[rowCount, columnCount];
// we then iterate through the 2D array
for (int row = 0; row < rowCount; row++)
{
// parse each number from string format to integer format & assign it to the corresponding location in our 2D array
string[] line = allLines[row].Split(' ');
for (int column = 0; column < columnCount; column++)
{
twoDArray[row, column] = int.Parse(line[column]);
}
}
This will give you a nice jagged 2D array that doesn't depend on all the text boxes having the same length. If you need them to all be the same length, it's trivial to check.
string[] data = // text input from all the text boxes
var result = data.Select(x => x.Split(' ')
.Select(y => int.Parse(y)).ToArray())
.ToArray();
Result is not quite an int[,] but an int[int[]], which is practically the same thing.
Of course, you need to deal with input validation or error handling.
Let me first start with the most naive solution, this makes very few assumptions about the data entered by the user. For example, it does not assume that every row has the same number of entries etc. So this could be optimized for those special conditions that you might know hold true or can enforce before running this routine.
// This is the data from the textbox
// hardcoded here for demonstration
string data = "1 1 1" + Environment.NewLine
+ "2 2 2" + Environment.NewLine
+ "12 12 12";
// First we need to determine the size of array dimension
// How many rows and columns do we need
int columnCount;
int rowCount;
// We get the rows by splitting on the new lines
string[] rows = data.Split(new string[]{Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries);
rowCount = rows.Length;
// We iterate through each row to find the max number of items
columnCount = 0;
foreach (string row in rows)
{
int length = row.Split(' ').Length;
if (length > columnCount) columnCount = length;
}
// Allocate our 2D array
int[,] myArray = new int[rowCount, columnCount];
// Populate the array with the data
for (int i = 0; i < rowCount; ++i)
{
// Get each row of data and split the string into the
// separate components
string[] rowData = rows[i].Split(' ');
for (int j = 0; j < rowData.length; ++j)
{
// Convert each component to an integer value and
// enter it into the 2D array
int value;
if (int.TryParse(rowData[j], out value))
{
myArray[i, j] = value;
}
}
}
Given the above where we are considering the possibility of each row not having the same number of elements, you might consider using a sparse array int[][] which coincidentally also yield better performance in .NET.

Defining Dynamic Array

How can I define a dynamic array in C#?
C# doesn't provide dynamic arrays. Instead, it offers List class which works the same way.
To use lists, write at the top of your file:
using System.Collections.Generic;
And where you want to make use of a list, write (example for strings):
List<string> mylist = new List<string>();
mylist.Add("First string in list");
Take a look at Array.Resize if you need to resize an array.
// Create and initialize a new string array.
String[] myArr = {"The", "quick", "brown", "fox", "jumps",
"over", "the", "lazy", "dog"};
// Resize the array to a bigger size (five elements larger).
Array.Resize(ref myArr, myArr.Length + 5);
// Resize the array to a smaller size (four elements).
Array.Resize(ref myArr, 4);
Alternatively you could use the List class as others have mentioned. Make sure you specify an initial size if you know it ahead of time to keep the list from having to resize itself underneath. See the remarks section of the initial size link.
List<string> dinosaurs = new List<string>(4);
Console.WriteLine("\nCapacity: {0}", dinosaurs.Capacity);
dinosaurs.Add("Tyrannosaurus");
dinosaurs.Add("Amargasaurus");
dinosaurs.Add("Mamenchisaurus");
dinosaurs.Add("Deinonychus");
If you need the array from the List, you can use the ToArray() function on the list.
string[] dinos = dinosaurs.ToArray();
C# does provide dynamic arrays and dynamic array manipulation. The base of an array is dynamic and can be modified with a variable. You can find the array tutorial here (https://msdn.microsoft.com/en-us/library/aa288453%28v=vs.71%29.aspx). I have also included code that demonstrates an empty set array and a dynamic array that can be resized at run time.
class Program
{
static void Main(string[] args)
{
int x = Convert.ToInt32(Console.ReadLine());
int y = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(x);
{
int[] dynamicArray1 = { };//empty array
int[] numbers;//another way to declare a variable array as all arrays start as variable size
numbers = new int[x];//setting this array to an unknown variable (will be user input)
for (int tmpInt = 0; tmpInt < x; tmpInt++)//build up the first variable array (numbers)
{
numbers[tmpInt] = tmpInt;
}
Array.Resize(ref numbers,y);// resize to variable input
dynamicArray1 = numbers;//set the empty set array to the numbers array size
for (int z = 0; z < y; z++)//print to the new resize
{
Console.WriteLine(numbers[z].ToString());//print the numbers value
Console.WriteLine(dynamicArray1[z].ToString());//print the empty set value
}
}
Console.Write("Dynamic Arrays ");
var name = Console.ReadLine();
}
}
Actually you can have Dynamic Arrays in C# it's very simple.
keep in mind that the response to your question above is also correct you could declare a
List Generic
The way to Create a Dynamic Array would be to declare your Array for example
string[] dynamicArry1 = { };//notice I did not declare a size for the array
List<String> tmpList = new List<string>();
int i = 1;
for(int tmpInt = 0; tmpInt < 5; tmpInt++)
{
tmpList.Add("Testing, 1.0." + tmpInt + ", 200, 3.4" + tmpInt +"," + DateTime.Now.ToShortDateString());
//dynamicArry1[tmpInt] = new string[] { tmpList[tmpInt].ToCharArray() };
}
dynamicArry1 = tmpList.ToArray();
how about ArrayList ?
If I'm not wrong ArrayList is an implementation of dynamic arrays
Example of Defining Dynamic Array in C#:
Console.WriteLine("Define Array Size? ");
int number = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter numbers:\n");
int[] arr = new int[number];
for (int i = 0; i < number; i++)
{
arr[i] = Convert.ToInt32(Console.ReadLine());
}
for (int i = 0; i < arr.Length; i++ )
{
Console.WriteLine("Array Index: "+i + " AND Array Item: " + arr[i].ToString());
}
Console.ReadKey();
like so
int nSize = 17;
int[] arrn = new int[nSize];
nSize++;
arrn = new int[nSize];

How do I create a string from one row of a two dimensional rectangular character array in C#?

I have a 2 dimensional array, like so:
char[,] str = new char[2,50];
Now, after I've stored contents in both str[0] and str[1], how do I store it in a
string[] s = new string[2];
?
I tried
s[0] = str[0].ToString();
but that seems to be an error: VC# expects 'two' indices within the braces, which means I can convert only a character from the array. Is there a way to convert the entire str[0] to a string? Or is changing it to a jagged array the only solution?
A jagged array is almost always the best solution for a variety of reasons, and this is one good example. There is so much more flexibility available with an array of arrays than with a multi-dimensional array. In this case, once you have the values in an array of chars, then a constructor on the string class can be used to create a string from it.
Also, the jagged array would be composed of "vectors" (i.e., a single-dimensional arrays with a zero-lower-bound index), which are much more preferment in .Net because they are given special treatment by the CLR.
So without knowing what the rest of your program is doing, that would be my recommendation.
If you do attempt to construct a string manually by looping through the array indexes, instead of using a jagged array, then I recommend using the StringBuilder class to do it.
I just banged this out, but it should be something like this:
// For the multi-dimentional array
StringBuilder sb = new StringBuilder();
for (int stringIndex = 0; stringIndex < s.Length; stringIndex++)
{
sb.Clear();
for (int charIndex = 0; charIndex < str.UpperBound(1); charIndex++)
sb.Append(str[stringIndex,charIndex]);
s[stringIndex] = sb.ToString();
}
// For the jagged array
for (int index = 0; index < s.Length; index++)
s[index] = new string(str[index]);
Assuming the dimensions are fixed as 2x50:
char[,] str = new char[2,50];
// populate str somehow
// chose which of the strings we want (the 'row' index)
int strIndex = 0;
// create a temporary array (faster and less wasteful than using a StringBuilder)
char[] chars = new chars[50];
for (int i = 0; i < 50; i++)
chars[i] = str[strIndex, i];
string s = new string[chars];
This would be easier and more performant if you used a jagged array:
char[][] str = new char[2][];
Then you could write:
string s = new string(characters[0]);
I would agree with using a jagged array. You can use this helper method to initialize a jagged array:
static T[][] InitJaggedArray<T>(int dimension1, int dimension2)
{
T[][] array = new T[dimension1][];
for (int i = 0; i < dimension1; i += 1)
{
array[i] = new T[dimension2];
}
return array;
}
So
char[,] str = new char[2,50];
would become
char[][] str = ArrayHelper.InitJaggedArray<char>(2, 50);
You would then access elements in it like so
str[0, 10] = 'a';
And to make it a string you would do
string s = new string(str[0]);
You can do it with LINQ:
string[] Convert(char[,] chars)
{
return Enumerable.Range(0, chars.GetLength(1))
.Select(i => Enumerable.Range(0, chars.GetLength(0))
.Select(j => chars[j, i]))
.Select(chars => new string(chars.ToArray());
}

Categories