🔹helpers
global functions
Array
arr.isMatrix - 可用來檢查 2D data 資料格式是否正確
arr.indexDictionaryForValues() - 找欄位索引 (column index)
arr.containsSubarray() - 檢查某列是否包含特定欄位名稱
const { keys } = Object;
const {log} = Logger;
/**
* ⭐ global functions:
* --------------------
* - typeName()
*
* ⭐ Array
* --------------------
* - sum()
* - average()
* - padEndSpaces(n)
* - rank()
* - indexDictionaryForValues()
* - containsSubarray()
* - removeDuplicates()
* - uniqueMerge()
* - isMatrix
*
* ⭐ String
* --------------------
* - removeWhitespaces()
*/
// ┌────────────┐
// │ Global Functions │
// └────────────┘
// 🔸 value's type
function typeName(value) {
// 01234567╭──╮↱ -1
// "[object XXXX]"
// ^^^^ <---- slice(8, -1)
return Object.prototype.toString.call(value).slice(8, -1);
}
// ┌──────┐
// │ Array │
// └──────┘
// 🔸 arr.sum()
Array.prototype.sum = function(){
return this.reduce((result, value) => result + value, 0);
};
// 🔸 arr.average()
Array.prototype.average = function(){
return this.sum() / this.length;
};
// 🔸 arr.padEndSpaces(n)
/**
* pad spaces ("") to the end of array
*
* @example
*
* const a = ['班級','座號','姓名'];
* a.padEndSpaces(3), // [ '班級', '座號', '姓名', '', '', '' ]
*
*/
Array.prototype.padEndSpaces = function(n) {
return this.concat(Array(n).fill(''));
};
// rank objects
/**
* rank array of objects
*
* @example
*
* students.rank('rankOfSchool', (a, b) => +b.total - +a.total);
*
*/
Array.prototype.rank = function(rankPropertyName, compare){
const sorted = this.sort(compare);
let current; // current object keeping the current rank
// 🧨 雷區:
// - indices (keys) of array.entries() are "integer-based"
// - indices (keys) of Object.entries(array) are "string-based"❗❗❗
for(const [i, obj] of sorted.entries()){
// 如果不同分,就產生新的班排名次,並記錄目前的總分與班排名次
if (!current || compare(current, obj) !== 0) {
obj[rankPropertyName] = i + 1;
current = obj;
}
// 如果同分,就用相同的班排。
else {
obj[rankPropertyName] = current[rankPropertyName];
}
}
return this; // for chaining
};
/*
* 🔸 array.indexDictionaryForValues(values)
* return the index for each value (a dictionary object)
*
* @example
*
* let row = ["座號", "姓名", "國語文", "英語文"];
* row.indexDictionaryForValues(["座號", "姓名"]) // { '座號': 0, '姓名': 1 }
*/
Array.prototype.indexDictionaryForValues = function(values){
let dict = {};
for(const value of values){
const i = this.indexOf(value);
if(i < 0) throw new Error(`⛔ array.indexDictionaryForValues(): array doesn't have value "${value}"`);
dict[value] = i;
}
return dict;
};
// 🔸 arr.containsSubarray()
Array.prototype.containsSubarray = function(subarray, orderIsRelevant=false) {
// ⭐ closure with internal parameter `i`
const valueIsInArraySequentially = (i => v => i = this.indexOf(v, i) + 1)(0);
const valueIsInArray = (v => this.includes(v));
const valuePassedTest = orderIsRelevant ? valueIsInArraySequentially : valueIsInArray;
return subarray.every(valuePassedTest);
};
// 🔸 array.removeDuplicates()
Array.prototype.removeDuplicates = function(){
return [... new Set(this)]
};
// 🔸 array.uniqueMerge()
Array.prototype.uniqueMerge = function(){
return this.flat().removeDuplicates();
};
// 🔸 arr.isMatrix
Object.defineProperty(Array.prototype, 'isMatrix', {
get(){
if (!this[0]) {
console.log(`ℹ️ array.isMatrix: array doesn't have first row. `);
return false;
}
function valueIsArray(value, i){
let isArray = Array.isArray(value);
if (!isArray) {
console.log(`ℹ️ array.isMatrix: array[${i}] is not an array.`);
return false;
}
return true;
}
// check if every value is an array.
if (!this.every((value, i) => valueIsArray(value, i))) return false;
// check if first row has elements
if (!this[0].length > 0) {
console.log(`ℹ️ array.isMatrix: first row has no values.`);
return false;
}
const arraySameLength = (array, i) => {
const len = array.length;
const len0 = this[0].length;
if (len !== len0){
console.log(`ℹ️ array.isMatrix: array[${i}].length (${len}) ≠ array[0].length (${len0}).`);
return false
}
return true;
}
// check if every array has the same length;
if (!this.every((arr, i) => arraySameLength(arr, i))) return false;
return true;
}
});
// ┌──────┐
// │ String │
// └──────┘
// 🔸 str.removeWhitespaces()
String.prototype.removeWhitespaces = function() {
return this.replace(/\s+/g, '');
};
object getter/setter
Last updated