If you want to display the matrix in the template without any logic on the typescript side, you could use the Array.prototype.slice to generate an array as long as your number of rows. Then iterate on that array with ngFor
and get the index from the index
variable, this will be your row index.
Then use an inner ngFor
and slice
again to get the row from your array and the row index.
You simply have to set n
to the number of items per row:
<div *ngFor="let row of arr.slice(0, arr.length / n % 1 === 0 ? arr.length / n : arr.length / n + 1); let idx = index">
<span *ngFor="let x of arr.slice(idx * n, idx * n + n)">{{ x }}</span>
</div>
See this stackblitz demo.
However, I think a more elegant solution would be to create a matrix from the array in typescript and then simply iterate on the rows and columns:
const arr = [1,2,3,4,5,6,7,8,9,10];
const n = 4;
const matrix = Array
.from({ length: Math.ceil(this.arr.length / this.n) }, (_, i) => i)
.map(i => this.arr.slice(i * this.n, i * this.n + this.n));
<div *ngFor="let row of matrix">
<span *ngFor="let x of row">{{ x }}</span>
</div>
Or you could create that matrix using a pipe in angular, something like this, with a row length of 4:
<div *ngFor="let row of arr | toMatrix:4">
<span *ngFor="let x of row">{{ x }}</span>
</div>
Then the pipe would hold the logic to create the matrix:
@Pipe({
name: 'toMatrix'
})
export class ToMatrixPipe implements PipeTransform {
transform(arr: number[], n: number): number[][] {
const rows = Array.from({ length: Math.ceil(arr.length / n) }, (_, i) => i);
return rows.map(idx => arr.slice(idx * n, idx * n + n));
}
}