Home > Net >  Pushing Values into Array
Pushing Values into Array

Time:06-16

I have a problem with populating an array based on another array.

It seems when I push a value onto a specific index in the array, it is populating all indexes.

Code

import { Component, VERSION } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  name = 'Angular '   VERSION.major;
  public matrix: number[] = [
    1, 2, 3, 4, 5, 6, 7, 8, 9.1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
    42, 43, 44, 45,
  ];
  public matrixColumns: number[][] = [];
  public expectedMatrixColumns: number[][] = [
    [1, 10, 19, 28, 37],
    [2, 11, 20, 29, 38],
    [3, 12, 21, 30, 39],
    [4, 13, 22, 31, 40],
    [5, 14, 23, 32, 41],
    [6, 15, 24, 33, 42],
    [7, 16, 25, 34, 43],
    [8, 17, 26, 35, 44],
    [9, 18, 27, 36, 45],
  ];
  public numberofColumns: number = 9;
  columnStartIndex: number = 0;

  constructor() {
    this.createColumnMatrix();
  }

  createColumnMatrix() {
    let columnsMatrix = [];
    let numberRows = this.matrix.length / this.numberofColumns;
    let matrixIndex = 0;

    for (let index = 0; index < this.numberofColumns; index  ) {
      this.matrixColumns.push([]);
    }
    let columnIndex: number = 0;
    this.matrix.forEach((number, matrixIndex) => {
      debugger;
      this.matrixColumns[columnIndex].push(this.matrix[matrixIndex]);
      debugger;
      matrixIndex = matrixIndex   1;
      columnIndex = columnIndex   1;
      if (columnIndex > this.numberofColumns - 1) {
        columnIndex = 0;
      }
    });
  }
}

Demo Project

Here is a JavaScript version that reproduces the problem:

class AppComponent {
  matrix = [
    1, 2, 3, 4, 5, 6, 7, 8, 9.1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
    42, 43, 44, 45,
  ];
  matrixColumns = [];
  expectedMatrixColumns = [
    [1, 10, 19, 28, 37],
    [2, 11, 20, 29, 38],
    [3, 12, 21, 30, 39],
    [4, 13, 22, 31, 40],
    [5, 14, 23, 32, 41],
    [6, 15, 24, 33, 42],
    [7, 16, 25, 34, 43],
    [8, 17, 26, 35, 44],
    [9, 18, 27, 36, 45],
  ];
  numberofColumns = 9;
  columnStartIndex = 0;

  constructor() {
    this.createColumnMatrix();
  }

  createColumnMatrix() {
    let columnsMatrix = [];
    let numberRows = this.matrix.length / this.numberofColumns;
    let matrixIndex = 0;

    for (let index = 0; index < this.numberofColumns; index  ) {
      this.matrixColumns.push(columnsMatrix);
    }
    let columnIndex = 0;
    this.matrix.forEach((number, matrixIndex) => {
      this.matrixColumns[columnIndex].push(this.matrix[matrixIndex]);
      matrixIndex = matrixIndex   1;
      columnIndex = columnIndex   1;
      if (columnIndex > this.numberofColumns - 1) {
        columnIndex = 0;
      }
    });
  }
}

let component = new AppComponent();
for (let row of component.matrixColumns) {
    console.log(JSON.stringify(row));
}

Problem

If you look at this line in the code:

this.matrixColumns[columnIndex].push(this.matrix[matrixIndex]);

It is pushing the first value in the array (matrix which is 1), into every index in my second array matrixColumns.

Expected output

[1, 10, 19, 28, 37]
[2, 11, 20, 29, 38]
[3, 12, 21, 30, 39]
[4, 13, 22, 31, 40]
[5, 14, 23, 32, 41]
[6, 15, 24, 33, 42]
[7, 16, 25, 34, 43]
[8, 17, 26, 35, 44]
[9, 18, 27, 36, 45]

Actual output

[1,2,3,4,5,6,7,8,9.1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45]
[1,2,3,4,5,6,7,8,9.1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45]
[1,2,3,4,5,6,7,8,9.1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45]
[1,2,3,4,5,6,7,8,9.1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45]
[1,2,3,4,5,6,7,8,9.1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45]
[1,2,3,4,5,6,7,8,9.1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45]
[1,2,3,4,5,6,7,8,9.1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45]
[1,2,3,4,5,6,7,8,9.1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45]
[1,2,3,4,5,6,7,8,9.1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45]

CodePudding user response:

you can do something like this

const buildMatrix = (data, columns) => data.reduce((res, d, i) => {
  const row = i % columns
  const rowData = [...(res[row] || []), d]
  res[row] = rowData
  return res
}, [])

const data = [
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
    42, 43, 44, 45,
  ];
  
const matrix = buildMatrix(data, 9)

console.log(matrix)

CodePudding user response:

you need two dimensions something like

this.matrixColumns[columnIndex][matrixIndex].push(this.matrix[columnIndex][matrixIndex]);

CodePudding user response:

The problem is that you only have one columnsMatrix array. After pushing its reference to this.matrixColumns repeatedly, you end up with multiple references to the same array. So whether you then push to this.matrixColumns[0] or to this.matrixColumns[1] doesn't make a difference, ... you're always pushing to the same array.

You can solve this by pushing a new array unto this.matrixColumns at every call of push.

So replace:

this.matrixColumns.push(columnsMatrix);

with:

this.matrixColumns.push([]);

Simplified code

Not your question, but you can do this as follows:

this.matrixColumns = Array.from({length: this.numberofColumns}, (_, i) =>
    Array.from({length: numberRows}, (_, j) => matrix[i   j*numberRows])
);

let matrix = [
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
    42, 43, 44, 45,
];
let numberofColumns = 9;
let numberofRows = Math.ceil(matrix.length / numberofColumns);
// logic
let matrixColumns = Array.from({length: numberofColumns}, (_, i) =>
    Array.from({length: numberofRows}, (_, j) => matrix[i   j*numberofRows])
);
// display
for (const row of matrixColumns) console.log(JSON.stringify(row));

  • Related