Stuck here trying to initialize an array (c#) using a loop. The number of rows will change depending. I need to get back two values that I am calculating earlier in the program startweek, and endweek. Lots of examples on building int arrays using loops but nothing I can find re dynamic strings and multi dim arrays.
Thanks
how do I set the values for col1 in string[,] arrayWeeks = new string[numWeeks, col1]; Is that clearer?
(Thanks for the clarification.) You can do a multidimensional initializer like so:
string[,] arrayWeeks = new string[,] { { "1", "2" }, { "3", "4" }, { "5", "6" }, { "7", "8" } };
Or, if your array is jagged:
string[][] arrayWeeks = new string[][]
{
new string[] {"1","2","3"},
new string[] {"4","5"},
new string[] {"6","7"},
new string[] {"8"}
};
If you're in a loop, I'm guessing you want jagged. And instead of initializing with values, you may want to call arrayWeeks[x] = new string[y]; where x is the row you're adding and y is the number of elements in that row. Then you can set each value: arrayWeeks[x][i] = ... where you are setting the ith element in the row. Your initial declaration of the array would be string[][] arrayWeeks = new string[numRows][];
So, to summarize, you probably want something that looks like this:
int numRows = 2;
string[][] arrayWeeks = new string[numRows][];
arrayWeeks[0] = new string[2];
arrayWeeks[0][0] = "hi";
arrayWeeks[0][1] = "bye";
arrayWeeks[1] = new string[1];
arrayWeeks[1][0] = "aloha";
But, obviously, within your loop.
There are two types of what you might call "multidimensional" arrays in C#. There are genuine multidimensional arrays:
string[,] array = new string[4, 4];
array[0, 0] = "Hello, world!";
// etc.
There are also jagged arrays. A jagged array an array whose elements are also arrays. The "rows" in a jagged array can be of different lengths. An important note with jagged arrays is that you have to manually initialize the "rows":
string[][] array = new string[4][];
for(int i = 0; i < 4; i++) {
array[i] = new string[4];
}
array[0][0] = "Hello, world!";
If the number of rows change depending on some factor (not fixed), it would be better to use a container, such as a List (see list on the MSDN). You can nest a list within a list to create a multi-dimensional list.
Late to the conversation, but here is a jagged array example when you setting the size and data dynamically:
// rowCount from runtime data
stringArray = new string[rowCount][];
for (int index = 0; index < rowCount; index++)
{
// columnCount from runtime data
stringArray[index] = new string[columnCount];
for (int index2 = 0; index2 < columnCount; index2++)
{
// value from runtime data
stringArray[index][index2] = value;
}
}
Related
I want to create array 10 * 10 * 10 in C# like int[][][] (not int[,,]).
I can write code:
int[][][] count = new int[10][][];
for (int i = 0; i < 10; i++)
{
count[i] = new int[10][];
for (int j = 0; j < 10; j++)
count[i][j] = new int[10];
}
but I am looking for a more beautiful way for it. May be something like that:
int[][][] count = new int[10][10][10];
int[][][] my3DArray = CreateJaggedArray<int[][][]>(1, 2, 3);
using
static T CreateJaggedArray<T>(params int[] lengths)
{
return (T)InitializeJaggedArray(typeof(T).GetElementType(), 0, lengths);
}
static object InitializeJaggedArray(Type type, int index, int[] lengths)
{
Array array = Array.CreateInstance(type, lengths[index]);
Type elementType = type.GetElementType();
if (elementType != null)
{
for (int i = 0; i < lengths[index]; i++)
{
array.SetValue(
InitializeJaggedArray(elementType, index + 1, lengths), i);
}
}
return array;
}
You could try this:
int[][][] data =
{
new[]
{
new[] {1,2,3}
},
new[]
{
new[] {1,2,3}
}
};
Or with no explicit values:
int[][][] data =
{
new[]
{
Enumerable.Range(1, 100).ToArray()
},
new[]
{
Enumerable.Range(2, 100).ToArray()
}
};
There is no built in way to create an array and create all elements in it, so it's not going to be even close to how simple you would want it to be. It's going to be as much work as it really is.
You can make a method for creating an array and all objects in it:
public static T[] CreateArray<T>(int cnt, Func<T> itemCreator) {
T[] result = new T[cnt];
for (int i = 0; i < result.Length; i++) {
result[i] = itemCreator();
}
return result;
}
Then you can use that to create a three level jagged array:
int[][][] count = CreateArray<int[][]>(10, () => CreateArray<int[]>(10, () => new int[10]));
With a little help from Linq
int[][][] count = new int[10].Select(x => new int[10].Select(x => new int[10]).ToArray()).ToArray();
It sure isn't pretty and probably not fast but it's a one-liner.
There is no 'more elegant' way than writing the 2 for-loops. That is why they are called 'jagged', the sizes of each sub-array can vary.
But that leaves the question: why not use the [,,] version?
int[][][] count = Array.ConvertAll(new bool[10], x =>
Array.ConvertAll(new bool[10], y => new int[10]));
A three dimensional array sounds like a good case for creating your own Class. Being object oriented can be beautiful.
You could use a dataset with identical datatables. That could behave like a 3D object (xyz = row, column, table)... But you're going to end up with something big no matter what you do; you still have to account for 1000 items.
Why don't you try this?
int[,,] count = new int[10, 10, 10]; // Multi-dimentional array.
Any problem you see with this kind of representation??
Given the following code:
List<int> Data = new List<int>();
Data.Add(1);
Data.Add(2);
Array[] tmp = new Array[Data.Count];
tmp[0] = Data.ToString().ToArray();
How to access the Data array in tmp[0]?
I have try tmp[0,0] or tmp[0].Data[0] but it doesn't work and gives me an error.
simple is can I add array to array onedimesion? if can how?
Just write
Array tmp;
tmp = Data.ToArray();
for(int x = 0; x < tmp.Length; x++)
Console.WriteLine(tmp.GetValue(x));
However I recommend to stick at using a strong typed List
Going deeper along this slippery path you could create an Array of Array (oh boy this start to get confusing)
// Create an array of two Array
Array[] tmp = new Array[Data.Count];
// First array set to the integer array
tmp[0] = Data.ToArray();
// Second array of strings
tmp[1] = new string[5];
// Set first element of the second array to a string
tmp[1].SetValue("Steve", 0);
Again, forget this approach and use more advanced collection classes like
Dictionary
Hashset
Tuple
If you want to access your data a a specific position just use
Data[Index]
if you realy want to use a array you can do
int[] array = Data.ToArray();
Must do like this.
List<int> Data = new List<int>();
Data.Add(1);
Data.Add(2);
int[] tmp = Data.ToArray();
Simply you can use
var array=Data.ToArray();
and if you want to add new item in array you might want to resize it first using
Array.Resize(ref array, array.Count() + 1);
array[array.Count()]=//your items here..
When adding. deleting use List<T>:
List<int> Data = new List<int>();
// Add item after item
Data.Add(1);
Data.Add(2);
// Add whole range of items, e.g. an array
Data.AddRange(new int[] {3, 4, 5});
int v = Data[0];
Data[0] = v + 10;
Console.Write(String.Join(", ", Data));
Finally, when you to have an array
int[] tmp = Data.ToArray();
// you still can read an item
int x = tmp[0];
// and write it
tmp[0] = x - 10;
But remember, you can't do tmp.Add() or tmp.RemoveAt()
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];
Say I have a rectangular string array - not a jagged array
string[,] strings = new string[8, 3];
What's the best way to extract a one-dimensional array from this (either a single row or a single column)? I can do this with a for loop, of course, but I'm hoping .NET has a more elegant way built in.
Bonus points for converting the extracted string array to an object array.
You can cast a string array to an object array trivially - going the other way doesn't work. The actual extraction has to use a for loop though, as far as I can see: Array.Copy requires the source and target ranks to be the same, and Buffer.BlockCopy only works for value type arrays. It does seem odd though...
You can use LINQ to extra a row or column in a single statement, although it will be inefficient (as it'll build up a list internally, then have to convert it to an array - if you do it yourself you can preallocate the array to the right size and copy directly).
Copying a row (rowNum is the row to be copied):
object[] row = Enumerable.Range(0, rowLength)
.Select(colNum => (object) stringArray[rowNum, colNum])
.ToArray();
Copying a column (colNum is the column to be copied):
object[] column = Enumerable.Range(0, columnLength)
.Select(rowNum => (object) stringArray[rowNum, colNum])
.ToArray();
I'm not sure that this is really any better/simpler than a foreach loop though - particularly if you write an ExtractRow method and an ExtractColumn method and reuse them.
For a rectangular array:
string[,] rectArray = new string[3,3] {
{"a", "b", "c"},
{"d", "e", "f"},
{"g", "h", "i"} };
var rectResult = rectArray.Cast<object>().ToArray();
And for a jagged array:
string[][] jaggedArray = {
new string[] {"a", "b", "c", "d"},
new string[] {"e", "f"},
new string[] {"g", "h", "i"} };
var jaggedResult = jaggedArray.SelectMany(s => s).Cast<object>().ToArray();
I'd just like to clarify (given the example and what's being asked).
A jagged array is an array of arrays and is declared like so:
string[][] data = new string[3][];
data[0] = new string[] { "0,[0]", "0,[1]", "0,[2]" };
data[1] = new string[] { "1,[0]", "1,[1]", "1,[2]" ];
data[2] = new string[] { "2,[0]", "1,[1]", "1,[2]" };
Versus a rectangular array being defined as a single array that holds multiple dimensions:
string[,] data = new string[3,3];
data[0,0] = "0,0";
data[0,1] = "0,1";
data[0,2] = "0,2";
...etc
Because of this, a jagged array is IQueryable/IEnumerable because you can iterate over it to receive an array at each iteration. Whereas a rectangular array is not IQueryable/IEnumerable because elements are addressed in full dimension (0,0 0,1..etc) so you won't have the ability to use Linq or any predefined functions created for Array in that case.
Though you can iterate over the array once (and achieve what you want) like this:
/// INPUT: rowIndex, OUTPUT: An object[] of data for that row
int colLength = stringArray.GetLength(1);
object[] rowData = new object[colLength];
for (int col = 0; col < colLength; col++) {
rowData[col] = stringArray[rowIndex, col] as object;
}
return rowData;
/// INPUT: colIndex, OUTPUT: An object[] of data for that column
int rowLength = stringArray.GetLength(0);
object[] colData = new object[rowLength];
for (int row = 0; r < rowLength; row++) {
colData[row] = stringArray[row, colIndex] as object;
}
return colData;
Hope this helps :)
LINQ is the answer
static object[] GetColumn(string[][] source, int col) {
return source.Iterate().Select(x => source[x.Index][col]).Cast<object>().ToArray();
}
static object[] GetRow(string[][] source, int row) {
return source.Skip(row).First().Cast<object>().ToArray();
}
public class Pair<T> {
public int Index;
public T Value;
public Pair(int i, T v) {
Index = i;
Value = v;
}
}
static IEnumerable<Pair<T>> Iterate<T>(this IEnumerable<T> source) {
int index = 0;
foreach (var cur in source) {
yield return new Pair<T>(index, cur);
index++;
}
}
Rows can be copied easily using Array.Copy:
int[][] arDouble = new int[2][];
arDouble[0] = new int[2];
arDouble[1] = new int[2];
arDouble[0][0] = 1;
arDouble[0][1] = 2;
arDouble[1][0] = 3;
arDouble[1][1] = 4;
int[] arSingle = new int[arDouble[0].Length];
Array.Copy(arDouble[0], arSingle, arDouble[0].Length);
This will copy the first row into the single Dimension array.
i made extention method. i dont know about the performance .
public static class ExtensionMethods
{
public static string[] get1Dim(this string[,] RectArr, int _1DimIndex , int _2DimIndex )
{
string[] temp = new string[RectArr.GetLength(1)];
if (_2DimIndex == -1)
{
for (int i = 0; i < RectArr.GetLength(1); i++)
{ temp[i] = RectArr[_1DimIndex, i]; }
}
else
{
for (int i = 0; i < RectArr.GetLength(0); i++)
{ temp[i] = RectArr[ i , _2DimIndex]; }
}
return temp;
}
}
usage
// we now have this funtionaliy RectArray[1, * ]
// -1 means ALL
string[] _1stRow = RectArray.get1Dim( 0, -1) ;
string[] _2ndRow = RectArray.get1Dim( 1, -1) ;
string[] _1stCol = RectArray.get1Dim( -1, 0) ;
string[] _2ndCol = RectArray.get1Dim( -1, 1) ;
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());
}