這幾天的進度推進緩慢究竟有沒有辦法順利完賽呢XD
今天跟著書上內容寫一個可迭代的資料結構
建立矩陣類別(Matrix class)並設定迭代器到矩陣類別中
簡單講就是個二維陣列,由行(cloumn)跟列(row)組成
一個 m x n 的矩陣,可以稱為 m-by-n matrix,也就是 m 列 n 行矩陣
矩陣裡的元素可以是數字,符號甚至是函式
補充一下說明,才會比較懂下面的程式碼在做什麼
假設建立一個 5x3 (寬度為5高度為3)的矩陣
實際上是建立從 [0,0] 到 [4,2] 的這些格子
邏輯上會先依序填滿 row
[0,0] [1,0] [2,0] [3,0] [4,0]
[0,1] [1,1] [2,1] [3,1] [4,1]
[0,2] [1,2] [2,2] [3,2] [4,2]
若要從 5x3 的矩陣中找到 [2,1] 於ㄧ維陣列的索引值(索引值會從0開始)
實際上一維陣列會這樣排序
[ [0,0] , [1,0] , [2,0] , [3,0] , [4,0] , [0,1] , [1,1] , [2,1] ]
其索引值會是 5x1+2=7
下方示例對應的程式碼就是
this.content[y * width + x] = element(x,y);
因此找[ x , y ]的索引值公式為矩陣寬 * y + x
// 建立矩陣
class Matrix{
constructor(width , height, element=(x,y)=> null){
this.width = width;
this.height = height;
this.content =[];
for(let y=0; y<height; y++){
for(let x=0; x<width; x++){
this.content[y * width + x] = element(x,y);
}
}
}
get(x,y){
return this.content[y * this.width +x];
}
set(x,y,value){
this.content[y * this.width + x] = value;
}
}
// 建立迭代器
class MatrixIterator{
constructor(matrix){
this.x = 0;
this.y = 0;
this.matrix = matrix;
}
// next method
next(){
if(this.y == this.matrix.height) return {done: true};
let value = {
x = this.x,
y = this.y,
value = this.matrix.get(this.x, this.y)
}
this.x ++;
if(this.x == this,matrix.width) {
this.x = 0;
this.y ++;
}
return {value, done: false};
}
}
將 [Symbol.iterator] 添加到 class Matrix上
class Matrix{
constructor(width , height, element=(x,y)=> null){
this.width = width;
this.height = height;
this.content =[];
for(let y=0; y<height; y++){
for(let x=0; x<width; x++){
this.content[y * width + x] = element(x,y);
}
}
}
//----add Symbol iterator to class Matrix
[Symbol.iterator] = function(){
return new MatrixIterator(this);
}
//----add Symbol iterator to class Matrix
get(x,y){
return this.content[y * this.width +x];
}
set(x,y,value){
this.content[y * this.width + x] = value;
}
}
然後便可以用 for..of 迴圈來循環檢查矩陣
let nuMatrix = new Matrix(2,2,(x,y)=>`value:${x},${y}`);
for(let {x,y,value} of nuMatrix){
console.log(x, y, value);
}
https://zh.wikipedia.org/zh-tw/%E7%9F%A9%E9%98%B5