Access Array with an Array of Indices

I wondered, if it was possible to access a specific element of a multidimensional array using an array, rather than multiple integers.

Like for example:

int[,] map = sampleMap;
int[] position = { 1, 2 };

sampleObject = map[position]; // This line won't work. "cannot implicitly convert type 'int[]' to 'int'"

Instead of:

sampleObject = map[position[1], position[2]]

Of course, when working with only 2 dimensions, it wouldn't be much of a problem, but imagine I had many dimensions, like 10:

map[position[1], position[2], position[3], ..., position[10]]

It would be much nicer and more elegant, to just write:

map[position]

I've been looking around, but the best I found was "How to access Arrays in [insert programming language here]" or "how to access elements from [insert Array type here]" or things like that.

Take a look at Array.GetValue(int[]) method

array of arrays (jagged arrays) are faster than multi-dimensional arrays and can be used more effectively. multidimensional arrays have nicer syntax.

if you write some simple code using jagged and multidimensional arrays and then inspect the compiled assembly with an il disassembler you will see that the storage and retrieval from jagged (or single dimensional) arrays are simple il instructions while the same operations for multidimensional arrays are method invocations which are always slower.

consider the following methods:

static void setelementat(int[][] array, int i, int j, int value)
{
    array[i][j] = value;
}

static void setelementat(int[,] array, int i, int j, int value)
{
    array[i, j] = value;
}

their il will be the following:

.method private hidebysig static void  setelementat(int32[][] 'array',
                                                    int32 i,
                                                    int32 j,
                                                    int32 'value') cil managed
{
  // code size       7 (0x7)
  .maxstack  8
  il_0000:  ldarg.0
  il_0001:  ldarg.1
  il_0002:  ldelem.ref
  il_0003:  ldarg.2
  il_0004:  ldarg.3
  il_0005:  stelem.i4
  il_0006:  ret
} // end of method program::setelementat

.method private hidebysig static void  setelementat(int32[0...,0...] 'array',
                                                    int32 i,
                                                    int32 j,
                                                    int32 'value') cil managed
{
  // code size       10 (0xa)
  .maxstack  8
  il_0000:  ldarg.0
  il_0001:  ldarg.1
  il_0002:  ldarg.2
  il_0003:  ldarg.3
  il_0004:  call       instance void int32[0...,0...]::set(int32,
                                                           int32,
                                                           int32)
  il_0009:  ret
} // end of method program::setelementat

when using jagged arrays you can easily perform such operations as row swap and row resize. maybe in some cases usage of multidimensional arrays will be more safe, but even microsoft fxcop tells that jagged arrays should be used instead of multidimensional when you use it to analyse your projects.

you are incorrect; jagged (nested) arrays are faster. (the clr is optimized for them)

java does not support true multi-dimensional arrays; that's a jagged array.
the java syntax automatically creates all of the inner arrays; in c#, that would need a separate loop.

you could use toarray(t[]).

import java.util.*;
public class test{
    public static void main(string[] a){ 
        list<string[]> list=new arraylist<string[]>();
        string[][] matrix=new string[list.size()][];
        matrix=list.toarray(matrix);
    }   
}

javadoc

why c/c++ is always preferable on large database/data-structure over java ? because, c may be, but c++ is also an oop. so, how it get advantage over java ?

remember that a java array (of objects)1 is actually an array of references. for simplicity let's look at a 1d array:

java:

[ref1,ref2,ref3,...,refn]
ref1 -> object1
ref2 -> object2
...
refn -> objectn

c++:

[object1,object2,...,objectn]

the overhead of references is not needed in the array when using the c++ version, the array holds the objects themselves - and not only their references. if the objects are small - this overhead might indeed be significant.

also, as i already stated in comments - there is another issue when allocating small objects in c++ in arrays vs java. in c++, you allocate an array of objects - and they are contiguous in the memory, while in java - the objects themselves aren't. in some cases, it might cause the c++ to have much better performance, because it is much more cache efficient then the java program. i once addressed this issue in this thread

2) should i stay on java or their suggestion (switch to c++) will be helpful in future on large database/data-structure environment ? any suggestion ?

i don't believe we can answer it for you. you should be aware of all pros and cons (memory efficiency, libraries you can use, development time, ...) of each for your purpose and make a decision. don't be afraid to get advises from seniors developers in your company who have more information about the system then we are.
if there was a simple easy and generic answer to this questions - we engineers were not needed, wouldn't we?

you can also profile your code with the expected array size and a stub algorithm before implementing the core and profile it to see what the real difference is expected to be. (assuming the array is indeed the expected main space consumer)


1: the overhead i am describing next is not relevant for arrays of primitives. in these cases (primitives) the arrays are arrays of values, and not of references, same as c++, with minor overhead for the array itself (length field, for example).


Tags: C# Java Arrays