Reference 2D Array Elements Like 1D Array

I have been working on a sub-routine in C++.

It takes in an array, testArray, treats it as a 1-D array, performs some operations on it, and then returns it to the main routine.
It also takes in two integers:
(i) arrSize, which specifies the size of the array, and
(ii) key, to indicate a position within that array.

For example,

void actOn1DArray(int arrSize, int key, double testArray[]){

double dumVar1;
int arrIndex1, i;

for (i = 0; i < arrSize; i++){

	arrIndex1 = i * arrSize;
	. . .
	
	dumVar1 = testArray[arrIndex1];
	arrIndex++;
	. . .
// Several more calculations;
     testArray[arrIndex1] = RESULT OF CALCULATIONS;
}

return;
}

The point of passing the parameters arrSize and key into the routine is so that the function can work with both a 1D and 2D array.
If testArray is 1D, the function is called with key = 1.
e.g.,

actOn1DArray(arrSize, 1, testArray);

If testArray is 2D, the function is called with key = arrSize and the address of the beginning of the array.
e.g.,

actOn1DArray(arrSize, arrSize, &testArray[0][0]);

By careful manipulation of the parameter key and the internal integer arrIndex1, this function can accept both a 1D and 2D array.
I have tested it thoroughly. It works.

Now I’d like to convert it to a JavaScript program.
However, I cannot find a way to pass a 2D array into a function and access it like a 1D array.

I have seen mention of the functions reduce and concat to flatten an array. In other words, a 2D array like
[[1,2, 3], [4, 5, 6], [7, 8, 9]] would be turned into [1, 2, 3, 4, 5, 6, 7, 8, 9]
Looks along the lines of what I want to do.
BUT, after the operations have been performed on the array, it is going to be returned to the main function as a 2D array. I just want to access its elements as a 1D array, not permanently turn it into a 1D array.

Is this possible in JavaScript?

It pretty much depends on what the array looks like and what you will be doing with it. There is a method Array.prototype.flat that will flatten an array, but as you say, you only want to access the array as if it were a one-dimensional array, not convert it into one.

Could you maybe provide some sample input and some sample output (i.e. what the function should accept and what it should return) as this might make it easier to make suggestions.

The input array is floating-point numbers, for example, a 5 x 5 array:

3.4     5.7      7.3      2.17    9.34
6.34    7.356    0.876    3.137   4.3333
7.345   8.43     7.11     4.22    1.123
5.567   5.22     4.908    5.43   11.2
4.32    8.386    2.625    1.23    4.125

The existing C++ program is written to treat this 2D array as a 1D array.
In C++, there are a few ways to do this. For the example above, since it is a 5 X 5 array, arrSize = 5 and I could use pointer arithmetic: The first element is at position *testArray(0) and all other elements are accessed in relation to that one. i.e., testArray[1][0] is equivalent to *testArray(5), testArray[2][0] is equivalent to *testArray(10), testArray[3][0] is equivalent to *testArray(15), etc. Since C++ uses row-based indexing, each testArray[i][j] element can be accessed as *testArray(j + arrSize * i).

Alternately, the way I use, is to create a dummy variable, arrIndex1, which holds the linear array index for the first element of each row (e.g., 0, 5, 10, 15, etc.) Then I work across each row.

The array elements are accessed, computations performed involving some additional dummy variables, and then the results of these computations are assigned back to the array elements. The 2D array is then returned to the main program, where the rest of the program, including several other sub-routines, treat it as a 2D array. So it cannot be changed to a 1D array.

Sorry, I’m still not following.

Given:

function manipulateArray(arr) {
  // manipulation
  // return something
}

const arr = [
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9, 10]
];

const result = manipulateArray(arr);

What should the result variable hold after the manipulateArray function has run?

There’s no need to repeat your complex logic here, but give an example that you could transfer to your situation (for example double the number, add one, whatever…).

Then, given:

function manipulateArray(arr) {
  // manipulation
  // return something
}

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

manipulateArray(arr);

What should the result variable hold after the manipulateArray function has run, having been passed a one dimensional array?

Frequently C++ accesses arrays as 1-dimensional objects for reasons of performance.

Is this the same reason why you want to to it in JavaScript? Because performance improvements don’t seem occur with JavaScript.

Another possible reason is to make for an easier conversion of code. Is that the case with JavaScript code? Because if so, there are frequently better techniques that can be employed instead.

It should be pointed out that .flat() returns a new array, it doesnt modify in-situ.

function actOn1Dor2DArray(inarray) {
  var flatarray = inarray.flat(); // 2D to 1D. Note that if you have more than 2D, flat will return N-1D by default.
  //Flat on an already 1D array returns the same array.
 //Do Your Calculation Here.
  return wargarble;
}

var test = [[0,1],[2,3],[4,5,6]];
var result = actOn1Dor2DArray(test);
//test still contains your array. result contains your result.

EDIT: Standard disclaimer: .flat() is an experimental function not fully adopted by browsers. In particular .flat() does not work in the Microsoft family of browsers.

A semi-modern approach to the same function: (Works on everything except IE. Because they’ve stopped feature-enhancing IE.)

var flatarray = [].concat(...inarray)

or if you absolutely must support every browser under the sun, even on the sunset horizon:

var flatarray = [];
inarray.forEach(function (x) {
    if(Array.isArray(x)) {
       flatarray = flatarray.concat(x);
    } else {
       flatarray.push(x);
    }
}

Yes. The present C++ version is able to accept either a 1D array or a 2D array. The input parameter arrSize ensures that the indexing works properly. I am really hoping to avoid writing one routine for 1D arrays and a separate routine for 2D arrays.

It is a lot more complicated than that. The program solves problems of Linear Algebra. Here is a brief description from the original FORTRAN program, going back MANY years: http://www.netlib.org/slatec/src/r1mpyq.f
The routine is called twice each loop of the main program, which may loop a thousand times. Once passing in a 2D array. Then later passing in a 1D array.

At this point, I don’t think JavaScript can do what I want, unless there is a lot of copying back and forth into dummy arrays.

But perhaps it can go the other way (i.e., reference a 1D array as a 2D array.) Say the routine is written to treat its input arrays as 2D arrays. Is this possible? Can 1D array elements be accessed using 2D array notation, for example, testArray[2][2]? Or define it as a N X 2 array, but treating the second row as all zeros, or something like that? Again, I only want to access it like a 2D array, I don’t want to permanently turn it into a 2D array. The rest of the program still needs to use it as a 1D array.

Would it be acceptable to use a recursive function? eg. in much abbreviated pseudocode

the_func(arg) 
each arg 
if typeof not array 
return value 
else 
return the_func(arg) 
.... 
vals = the_func(src_array) 

That might work. Thanks for the suggestion.

The other option I was considering is a few if statements, within a loop, within a loop.

In any case, it looks like whatever I do won’t be pretty, so I am going to mull things over and figure something out. I think we have beat this horse to death–and then some.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.