Argh! I know I will get this eventually but at this point I'm almost 2 hours into it and still stuck.
I need to resolve the individual indexes for each "level" of a jagged array for a specific location. It's hard to explain, but if you imagine a 3 level jagged array with [2,3,4] lengths. If you then were to flatten that out into a single array it would have a size of 24. Now, let's say you needed to find the the indexes (one for each level of the jagged array) that would be equal to the single array index 22. It would be 1,2,1. It's not hard to figure out a single scenario, but I'm trying to figure out what the algorithm is to resolve these values for a variable depth jagged array.
Here is a simple code sample of my current attempt:
using System;
class Program
{
static void Main(string[] args)
{
// Build up the data and info about level depth
int[] levelDepth = new[] { 2, 3, 4 };
int[][][] data = new int[][][]
{
new int[][] { new int[4], new int[4], new int[4] },
new int[][] { new int[4], new int[4], new int[4] }
};
int requestedValue = 22;
float temp = requestedValue;
// Store the index of each level array to get to the index
// for the requested value
int[] levelIndexes = new int[3] { 0, 0, 0 };
// The following does not work!
int i = levelDepth.Length;
while (i > 0)
{
temp = temp / levelDepth[i - 1];
levelIndexes[i - 1] = (int)Math.Round(temp);
i--;
}
}
}
It doesn't work correctly, although it ALMOST gets me what I need but I think that just may be luck. I suspect this is a common problem that has been solved before, I just don't have the experience to figure it out. :(
Also, before anyone tells me that using arrays like this is terrible or "why don't you store your data like this" - The above description and code is simulating the layout of some decoder chips on our hardware and I need to work out a way to resolve a path to a specific graph of cascading chips; the above example exactly matches the layout of the chips. I'm stuck with it.
You shouldn't use float
s here.
int[] levelDepth = new[] { 2, 3, 4 };
int requestedValue = 22;
int[] levelIndexes = new int[levelDepth.Length];
for (int i = 0; i < levelDepth.Length; i++)
{
// need to go from { 2, 3, 4 } -> { 3*4, 4, 1 }
int f = 1;
for (int j = i+1; j < levelDepth.Length; j++)
f *= levelDepth[j];
levelIndexes[i] = requestedValue / f; // integer divide
requestedValue = requestedValue % f;
}
Assuming you need the element's value at that point (and not the specific indices), you can simply perform a ruby-like flatten, and then access the index directly.
Edit: Sorry for the misunderstanding, maybe this will help. From Microsoft Visual C#.NET 2003 Developers Cookbook (Mark Schmidt):
static int[] GetDimensionIndices(int flatIndex, Array array)
{
int[] indices = new int[array.Rank];
int p = 1;
for(int i = array.Rank - 1; i >= 0; i--)
{
indices[i] = (((flatIndex/p)) % (array.GetUpperBound(i)+1));
if(i > 0)
p *= array.GetUpperBound(i) + 1;
}
return indices;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With