I have an N-dimensional array which I want to be able to assign any primitive value to. (one type for single array, but alg must be generic for all primitive types).
I've written a method which can do this:
var element = Array.CreateInstance(dataType, dataDims);
foreach (var index in GetIndexes(dataDims))
{
element.SetValue(SomeKindOfValue, index);
}
The function GetIndexes generates all possible indexes for the given dimensions:
public static IEnumerable<int[]> GetIndexes(int[] dims)
{
int lastIndex = dims.Length - 1;
int lastDim = dims[lastIndex];
int[] Index = new int[dims.Length];
int currentDim = lastIndex;
while (currentDim >= 0)
{
if (currentDim == lastIndex)
{
for (int i = 0; i < lastDim; i++)
{
yield return Index;
Index[currentDim]++;
}
Index[currentDim] = 0;
currentDim--;
continue;
}
else
{
if (Index[currentDim] == dims[currentDim] - 1)
{
Index[currentDim] = 0;
currentDim--;
continue;
}
else
{
Index[currentDim]++;
currentDim = lastIndex;
continue;
}
}
}
}
EXAMPLE: for GetIndexes(new int[] {4,2,3}) the output will be:
0, 0, 0 |
0, 0, 1 |
0, 0, 2 |
0, 1, 0 |
0, 1, 1 |
0, 1, 2 |
1, 0, 0 |
1, 0, 1 |
1, 0, 2 |
1, 1, 0 |
1, 1, 1 |
1, 1, 2 |
2, 0, 0 |
2, 0, 1 |
2, 0, 2 |
2, 1, 0 |
2, 1, 1 |
2, 1, 2 |
3, 0, 0 |
3, 0, 1 |
3, 0, 2 |
3, 1, 0 |
3, 1, 1 |
3, 1, 2 |
The problem is, that assigning values this way is time-costly, and this alg need to be as efficient as possible.
I was thinking that multidimensional array is actually 1d array in the memory, so if I could access the pointer of each element, then I could assign the values w/o any calculations, and directly. The problem is that I was unable to find a way to create a pointer to a generic class Array(or to it's first element).
Basically, I'm trying to write a generic func of this (which will accept any primitive type as datatype of array, and will accept any multidimensional array):
public static unsafe void SetElementsByPointer(int[,] array, int[] values)
{
if (values.Length != array.LongLength)
throw new Exception("array and values length mismatch.");
fixed (int* pStart = array)
{
for (int i = 0; i < array.LongLength; i++)
{
int* pElement = pStart + i;
*pElement = values[i];
}
}
}
I will appreciate any other ideas for setting values into n-dimensional array, but the pointer way seems the most efficient, just that I can't figure it out
Thanks in advance.
To copy stuff, you may use this: https://dotnetfiddle.net/vTzJv4
// 1D array
int[] values = new int[] {
1, 2, 3,
4, 5, 6
};
// 2D array
int[,] marr = new int[2,3];
// Copy here
System.Buffer.BlockCopy((Array)values, 0, (Array)marr, 0, (int)marr.LongLength * sizeof(int));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.