Nested loops shortcut in Javascript?

Viewed 785

In a program I'm writing I have a multidimensional array and I need to perform some operation only on the most inner objects.

Is there any better way to write this code?

for (const threeDimensionalArray of fourDimensionalArray) {
  for (const twoDimensionalArray of threeDimensionalArray) {
    for (const oneDimensionalArray of twoDimensionalArray) {
      for (const obj of oneDimensionalArray) {
        // do something
      }
    }
  }
}

Something like:

for (const obj someSpecialKeyword fourDimensionalArray) {
  // do something
}

Note: I know of one solution which is using a flattening function. The problem with using a flattening function is that this iteration is going to be used a lot in the program so I am worried about the performance. Even if I save this multidimensional array in two formats (a flat one and a multidimensional one) it can cause performance issues because this array is also changed a lot and also makes the code longer.

What would be the best approach here?

2 Answers

I know of one solution which is using a flattening function

I assume by "flattening function" you mean a Reducer function? (It is unfortunate that JavaScript's Array.prototype functions, such as reduce, map, filter, etc perform full copies on every step).

An alternative is to write a Generator Function (aka Iterator Function):

function* getAll( fourDimensionalArray ) { // The asterisk is not a typo.
    for (const threeDimensionalArray of fourDimensionalArray) {
        for (const twoDimensionalArray of threeDimensionalArray) {
            for (const oneDimensionalArray of twoDimensionalArray) {
                for (const obj of oneDimensionalArray) {
                    yield obj;
                }
            }
        }
    }
}

Used like so:

for( const item of getAll( fourDimensionalArray ) ) {
    // do something
}

Generator functions are very efficient and do not cause an array copy operation.

You could take a recursive function which take an array or item and a callback for non arrays.

This function does not rely on a fixed structure.

function iter(value, cb) {
    if (Array.isArray(value)) {
        for (const item of value) iter(item, cb);
    } else {
        cb(value);
    }
}
Related