I'm developing, just for fun and learning, a TypeScript Class that creates an Array<Array<string>>
that represents a pyramid. So, for length = 5
the array would look like :
[
['X', 'X', '0', 'X', 'X'],
['X', '0', '0', '0', 'X'],
['0', '0', '0', '0', '0']
]
The class constructor can take a few arguments:
- The final array.
- The length (width) of the pyramid, the "blank" String and the "piece" string
My implementation looks like:
interface IPiramide {
array? : Array<Array<string>>,
private blanco? : string = 'X',
private trozo? : string = 'O'
}
class Piramide implements IPiramide {
constructor(piramide : IPiramide = {blanco : 'X', trozo : '0', ancho : 0}){
this.blanco = piramide.blanco;
this.trozo = piramide.trozo;
if(piramide.array){
this.array = piramide.array;
}
else if(piramide.ancho){
this.build(piramide.ancho);
}
}
static getInstance(ancho : number, blanco : string, trozo : string, inverse ? : boolean) : Piramide {
return new Piramide({blanco, trozo}).build(ancho, inverse);
}
private build (ancho : number, inverse? : boolean = false) {
this.array = [];
let numberCount = ancho % 2 == 0 ? 2 : 1;
let middle = Math.floor(ancho / 2);
while (numberCount != ancho + 2){
this.array.push(Array.from({length : ancho}, (el, idx)=>{
let range = (ancho - numberCount)/2;
return (idx < range || idx > ancho - range - 1)
? this.blanco
: this.trozo;
}));
numberCount += 2;
}
inverse
? this.array = this.array.map((el, idx, arr)=>arr[arr.length - idx - 1])
: this.array;
return this;
}
public getArray (){
return this.array;
}
public getTrozo() {
return this.array[Math.floor(this.array.length/2)][Math.floor(this.ancho/2)];
}
public getBlanco(){
if(this.array.length){
return this.array[1][0];
}
return null;
}
public getAncho(){
return this.array[0].length;
}
public getAlto(){
return this.array.length;
}
toString(){
return this.array.map( el=> el.join(' ')).join('\n');
}
isConcatenable (piramide : Piramide) : boolean {
console.log('isConcat', this);
return this.getAlto() == piramide.getAlto();
}
reverse() : Piramide{
this.array = this.array.map( (el, idx, arr) => arr[arr.length - idx - 1]);
return this;
}
concatRight (...piramides : Array<Piramide>) : Piramide {
return new Piramide({
array : this.array.map( (el, i)=> el.concat(...piramides.filter(this.isConcatenable.bind(this)).map( pir => pir.getArray()[i] ) ) ),
blanco : this.blanco,
trozo : this.trozo
});
}
concatLeft (...piramides : Array<Piramide>) : Piramide {
return new Piramide({
array : this.array.map( (el, i)=> [].concat(...piramides.filter(this.isConcatenable.bind(this)).map( pir => pir.getArray()[i] ) ) ).map( (el, i)=> el.concat(this.array[i])),
blanco : this.blanco,
trozo : this.trozo
});
}
concatAbove(...piramides : Array<Piramide>) {
return new Piramide({
array : piramides.reduce( (arr, pir) => arr.concat(pir.getArray()) , []).concat(this.array),
blanco : this.blanco,
trozo : this.trozo
});
}
concatBelow(...piramides : Array<Piramide>) {
return new Piramide({
array : this.array.concat(piramides.reduce( (arr, pir) => arr.concat(pir.getArray()) , [])),
blanco : this.blanco,
trozo : this.trozo
});
}
}
It works, but it seems to me that this could be improved (I feel weird with my constructor and static methods).
Could this code be improved?