# array & matrix methods

{% tabs %}
{% tab title="💾 程式" %}
```javascript
const array_matrix_methods = {
    
    // ---------------------
    //     array methods
    // ---------------------
    
    // arr.isEmpty
    get isEmpty() { return this.length === 0 },
    
    // arr.last
    get last() { return this[this.length - 1] },
    
    // arr.max(f): f must be a real-valued function
    max(f=x=>x){ return Math.max(...this.map(x => f(x)))},

    // ------------------------
    //     2D array methods
    // ------------------------

    // assuming:
    // - elements in array are themselves arrays.
    // - an element in array is called a "row".

    // arr2d.numberOfRows
    get numberOfRows() { return this.length },
    
    // arr2d.maxRowLength
    get maxRowLength() { return this.max(row => row.length) },

    // arr2d.maxColumnIndex
    get maxColumnIndex() { return this.maxRowLength - 1 },

    // arr2d.transpose
    get transpose() {
        return Array.from({length: this.maxRowLength}, (_, j) => 
            this.map(row => row[j])
        );
    },

    // arr2d.map2D()
    map2D(f) {
        return this.map((row, i) => 
            row.map((value, j) => f(value, i, j))
        )
    },

    // ---------------------
    //     matrix methods
    // ---------------------

    // assuming:
    // - every element (row) is still an array of the same length

    // matrix.numberOfColumns
    get numberOfColumns() { return this[0].length },
};
```
{% endtab %}

{% tab title="💈範例" %}
⬆️ 需要： [.assigndescriptors](../../obj/extend/mixin/.assigndescriptors "mention")

* [replit](https://replit.com/@pegasusroe/array-and-matrix-methods#index.js)

```javascript
// ⭐ extending Array.prototype
Object.assignDescriptors(Array.prototype, array_matrix_methods);

// test data
let arr = [1, 2, 5, 50, 10];
let filtered = arr.filter(x => x >= 10);    //

let arr2d = [
    [1,2,3],
    [1,2,3,4],
    [1,2]
];

// ---------------- output -----------------
arr.isEmpty,             // false
arr.last,                // 10
arr.max(),               // 50

filtered,                // [ 50, 10 ]
filtered.isEmpty,        // false

arr2d.numberOfRows,      // 3
arr2d.maxRowLength,      // 4

arr2d.map2D((_, i, j) => i === j ? 1 : 0),
// [ [ 1, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0 ] ]

arr2d.transpose,
// [
//   [ 1, 1, 1 ],
//   [ 2, 2, 2 ],
//   [ 3, 3, undefined ],
//   [ undefined, 4, undefined ]
// ]
```
{% endtab %}

{% tab title="📘 手冊" %}
* [Object.defineProperty()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)
{% endtab %}
{% endtabs %}
