I would like to use a row and column removing method in my array. Therefore I wanted to convert my array to ArrayList to use the RemoveAt(int index) method, but in Windows 8 Apps using .NET 4.5 there is no ArrayList. Could you give me a suggestion how to cast my simple int[,] array to another type, which has a row and column removing method?
You could just use a list of lists:
List<List<int>> array = new List<List<int>>();
And initialize it as follows
for (int i = 0; i < orig_array.Length, i++)
{
array.Add(new List<int>(orig_array[i]));
}
Using this approach, array.RemoveAt(row) would remove an entire row, whereas array[row].RemoveAt(col) would remove an element.
EDIT: As phoog indicated, the above initialization would need to be modified for an array declared as int[,], as follows:
for (int row = 0; row < orig_array.GetLength(0), row++)
{
array.Add(new List<int>());
for (int col = 0; col < orig_array.GetLength(1); col++)
{
array[row].Add(orig_array[row, col]);
}
}
The advantage to using a jagged array (as opposed to a rectangular array) in this case is being able to access entire rows, without the need to explicitly loop through the values.
The ArrayList and all non-generic collections for been removed from WinRT. This link here will help you with replacing the the arraylist.
Related
I have an Array variable. I can use the Rank property to get the number of dimensions and I know that you can use a foreach to visit each element as if the array was flattened. However, I wish to modify elements and change element references. I cannot dynamically create the correct number of for loops and I cannot invalidate an enumerator.
EDIT
Thanks for the comments, sorry about the previous lack of clarity at the end of a long tiring day. The problem:
private void SetMultiDimensionalArray(Array array)
{
for (int dimension = 0; dimension < array.Rank; dimension++)
{
var len = array.GetLength(dimension);
for (int k = 0; k < len; k++)
{
//TODO: do something to get/set values
}
}
}
Array array = new string[4, 5, 6];
SetMultiDimensionalArray(array);
Array array = new string[2, 3];
SetMultiDimensionalArray(array);
I had another look before reading this page and it appears all I need to do is create a list of integer arrays and use the overloads of GetValue and SetValue -
Array.GetValue(params int[] indices)
Array.SetValue(object value, params int[] indices)
Everything seems clear now unless someone can suggest a superior method. svick has linked to this so I will accept this answer barring any further suggestions.
It's hard to tell what exactly do you need, because your question is quite unclear.
But if you have a multidimensional array (not jagged array) whose rank you know only at runtime, you can use GetValue() to get the value at specified indices (given as an array of ints) and SetValue() to set it.
I have array defined like this :
List<DocumentFields>[,] dummyArray = new List<DocumentFields>[8,8];
It takes records from the database. I need to prepare this array for showing in a asp.net mvc3 view so i iterate it the standard way :
for (int i = 0; i < ViewBag.Header.GetLength(0); i++)
{
for (int j = 0; j < ViewBag.Header.GetLength(1); j++)
{
But I realized that in fact for the second iteration I don't need the Length but the count of the elements that are actually there. So instead of ViewBag.Header.GetLength(1) I need this:
ViewBag.Header.Get_Count_Of_The_Elements_For_The_Second_Index
I couldn't find a property that do this right away. Maybe some way of using Length or something... Dunno...
Your dummyArray is a two-dimensional array of lists. To get list size you can use dummyArray[i,j].Count in your inner loop.
I initialized an Array as
Double[][] myarr = Enumerable.Repeat(new double[12], 13).ToArray();
Then in a loop i am incrementing values like
myarr[0][0]++;
This causes all values like myarr[1][0], myarr[2][0], myarr[3][0] ..... myarr[12][0] to increment by one.
This problem is not occurring when using a for loop (0-12) i am initializing like
myarr[i] = new double[12];
Why is this so?
Other answers have explained the problem. The solution is to create a new array on each iteration, e.g.
double[][] myarr = Enumerable.Range(0, 13)
.Select(ignored => new double[12])
.ToArray();
It's because new double[12] creates a single array object in memory - Enumerable.Repeat is simply providing you with multiple references to that array.
This is expected behavior - array is a referebce type. You are creating a jagged array i.e. array of arrays. All elements of your outer array references the same inside array i.e the first argument of Repeat call, so changes in the inside array will be reflected at on indices (because all indices refer to the same array).
With new double[12] you are creating reference to array of doubles, and then you repeate the reference 12 times, so myarr[0..n] will have reference to one memory region.
You can use the folowing method to resolve thw issue
static T[][] CreateArray<T>(int rows, int cols)
{
T[][] array = new T[rows][];
for (int i = 0; i < array.GetLength(0); i++)
array[i] = new T[cols];
return array;
}
Or with custom Repeat method which calls action every step:
public static IEnumerable<TResult> RepeatAction<TResult>(Action<TResult> elementAction, int count)
{
for (int i = 0; i < count; i++)
{
yield return elementAction();
}
yield break;
}
usage
RepeatAction(()=>new double[12], 12);
Arrays are references. In the Repeat call you create one array and assign its reference 12 times. In your loop however you create 12 distinct arrays.
Repeat() basically just capture and yields the same element multiple times, so you got multiple references to the same object instance in the memory.
This is how Repeat() is implemented:
private static IEnumerable<TResult> RepeatIterator<TResult>(TResult element, int count)
{
for (int i = 0; i < count; i++)
{
yield return element;
}
yield break;
}
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));
}
I am taking the data into a 2d string in C#.
Defined as ::
string[,] strValueBasic = new string[GridView1.Rows.Count,49];
Now i want the data to be taken into DataRows and add these rows into the DataTable.
for (int i = 0; i < GridView1.Rows.Count; i++)
{
DataRow drRow = dtNew.NewRow();
drRow.ItemArray = strValueBasic[i];
dtNew.Rows.Add(drRow);
}
But i am not able to access this 2d String array in the step
drRow.ItemArray = strValueBasic[i];
It is giving error as Wrong number of indices inside [], expected 2.
I know that it requires 2 indices, but than i want the whole row of that string array to be filled inside that DataRow.
Also the structure of DataRow and String Array is same.
If you want to assign whole row your strValueBasic should be defined as string[][]. Not the 2D array but array of arrays. That changes initialization too, each array can have different size so you have to create each separately. http://msdn.microsoft.com/en-us/library/2s05feca.aspx
Thats because strValueBasic is a 2D array and you're trying to access it as it's a 1D array.
for (int i = 0; i < GridView1.Rows.Count; i++)
{
DataRow drRow = dtNew.NewRow();
drRow.ItemArray = strValueBasic[i, iSomeOtherValue];
dtNew.Rows.Add(drRow);
}
Notice iSomeOtherValue, you're missing something!