Reputation: 1236
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.
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;
}
});
}
}
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));
}
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
.
[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]
[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]
Upvotes: 0
Views: 87
Reputation: 351359
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([]);
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));
Upvotes: 0
Reputation: 1035
you need two dimensions something like
this.matrixColumns[columnIndex][matrixIndex].push(this.matrix[columnIndex][matrixIndex]);
Upvotes: 0
Reputation: 7139
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)
Upvotes: 3