3
\$\begingroup\$

I need help to dynamically create an array with nested objects holding again an array of objects each. The structure is as follows:

tiles=[
     { "row": [{isChecked: true, src: ''}, {isChecked: true, src: ''}, {isChecked: true, src: ''}] },
     { "row": [{isChecked: true, src: ''}, {isChecked: true, src: ''}, {isChecked: true, src: ''}] },
     { "row": [{isChecked: true, src: ''}, {isChecked: true, src: ''}, {isChecked: true, src: ''}] },
     { "row": [{isChecked: true, src: ''}, {isChecked: true, src: ''}, {isChecked: true, src: ''}] }
  ];

However, the amount of row objects and amount of rows is dynamic. In the example above, it's 3 x 4.

My current approach is a simple nested loop:

updateTileEditor(x: number, y: number) {
  this.tiles = [];
  for (var i = 0; i < y; i++) {
    let helperArray = [];
    for (var j = 0; j < x; j++) {
      helperArray.push({ isChecked: true, src: '' });
    }
    this.tiles.push({ "row": helperArray });
  }
}

Could you perhaps propose a more feasable approach to this?

Be aware that every nested object of the nested array must be a different object. In other words, the objects can not point to the same reference.

Thanks in advance!

\$\endgroup\$
  • 1
    \$\begingroup\$ I'm having a hard time following you. Perhaps if we understood the application of the function we might be able to assist you in refactoring. For instance, what does "Be aware that every nested object of the nested array must be a different object. In other words, the objects can not point to the same reference." mean? No two sub-objects can be the same or that sub-objects can't be the same as a parent level object? I see no logic in your current function to check any of this, so I'm confused as to what you're trying to communicate. \$\endgroup\$ – technicallynick Dec 6 '19 at 20:14
3
\$\begingroup\$

I can propose more functional approach. I don't have arguments to say that it's better, it's just how I prefer to write code for generating two-dimensional arrays filled with some initial values.

function createRow(rowLength: number) {
    return Array(rowLength).fill(null).map(() => ({
        isChecked: true,
        src: ''
    }))
}

function updateTileEditor(length: number, height: number) {
    this.tiles = Array(height).fill(null).map(() => ({
        row: createRow(length)
    }));
}

Explanation:

  • Array(height) creates an empty array of fixed size height - we want to create height rows.
  • .fill(null) is used to fill the array with any values, so you can map these values to new ones. Any other value can be used instead of null. Mapping empty array would return us new empty array.
  • .map(() => createRow(rowLength)) creates new array in which each value is a new row. () => createRow(rowLength) gets called for each value in the array, so you can be sure that you will have new row for each value.

I also renamed x to length and y to height - these names are more descriptive, which I think can help new readers with figuring out the purpose of these variables.

I will write it here, because I don't have enough reputation to comment: you could also use arrays for rows instead of objects that have one property called "row". If you have only one value then maybe you don't need to wrap it in an object? - I guess I would need more details about the problem to say that.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.