iT邦幫忙

2025 iThome 鐵人賽

DAY 18
0

這幾天的進度推進緩慢
究竟有沒有辦法順利完賽呢XD

今天跟著書上內容寫一個可迭代的資料結構
建立矩陣類別(Matrix class)並設定迭代器到矩陣類別中

什麼是矩陣(Matrix)

簡單講就是個二維陣列,由行(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


上一篇
Chapter 6 物件的秘密([Symbol.iterator])-day17
下一篇
Chapter 6 物件的秘密(getter, setter/ type of method)-day19
系列文
溫故而知新:Eloquent Javascript 閱讀筆記19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言