├── Add Two Promises.js ├── Allow One Function Call.js ├── Apply Transform Over Each Element in Array.js ├── Array Prototype Last.js ├── Array Reduce Transformation.js ├── Array Wrapper.js ├── Cache With Time Limit.js ├── Calculator with Method Chaining.js ├── Chunk Array.js ├── Compact Object.js ├── Counter II.js ├── Counter.js ├── Create Hello World Function.js ├── Debounce.js ├── Event Emitter.js ├── Execute Asynchronous Functions in Parallel.js ├── Filter Elements from Array.js ├── Flatten Deeply Nested Array.js ├── Function Composition.js ├── Group By.js ├── Interval Cancellation.js ├── Is Object Empty.js ├── Join Two Arrays by ID.js ├── Memoize.js ├── Promise Time Limit.js ├── README.md ├── Return Length of Arguments Passed.js ├── Sleep.js ├── Sort By.js ├── Timeout Cancellation.js └── To Be Or Not To Be.js /Add Two Promises.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Promise} promise1 3 | * @param {Promise} promise2 4 | * @return {Promise} 5 | */ 6 | var addTwoPromises = async function(promise1, promise2) { 7 | // Wait for both promises to resolve and retrieve their values 8 | const [value1, value2] = await Promise.all([promise1, promise2]); 9 | 10 | // Return a new promise that resolves with the sum of the values 11 | return value1 + value2; 12 | }; 13 | 14 | // // Example usage: 15 | // var promise1 = new Promise(resolve => setTimeout(() => resolve(2), 20)); 16 | // var promise2 = new Promise(resolve => setTimeout(() => resolve(5), 60)); 17 | 18 | // addTwoPromises(promise1, promise2) 19 | // .then(console.log); // Output: 7 -------------------------------------------------------------------------------- /Allow One Function Call.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Function} fn 3 | * @return {Function} 4 | */ 5 | var once = function(fn) { 6 | 7 | let hasBeenCalled = false; 8 | let result; 9 | 10 | return function(...args) { 11 | if (!hasBeenCalled) { 12 | result = fn(...args); 13 | hasBeenCalled = true; 14 | return result; 15 | } else { 16 | return undefined; 17 | } 18 | } 19 | 20 | }; 21 | 22 | let fn = (a,b,c) => (a + b + c); 23 | let onceFn = once(fn); 24 | 25 | console.log(onceFn(1,2,3)); // 6 26 | console.log(onceFn(2,3,6)); // undefined -------------------------------------------------------------------------------- /Apply Transform Over Each Element in Array.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} arr 3 | * @param {Function} fn 4 | * @return {number[]} 5 | */ 6 | var map = function(arr, fn) { 7 | 8 | var arra=[]; 9 | for(i=0;i acc + val, 0) 16 | } 17 | 18 | /** 19 | * @return {string} 20 | */ 21 | ArrayWrapper.prototype.toString = function() { 22 | // return string from array join and template literals 23 | return `[${this.nums.join(',')}]` 24 | } 25 | 26 | /** 27 | * const obj1 = new ArrayWrapper([1,2]); 28 | * const obj2 = new ArrayWrapper([3,4]); 29 | * obj1 + obj2; // 10 30 | * String(obj1); // "[1,2]" 31 | * String(obj2); // "[3,4]" 32 | */ -------------------------------------------------------------------------------- /Cache With Time Limit.js: -------------------------------------------------------------------------------- 1 | const TimeLimitedCache = function() { 2 | this.cache = new Map(); // Using Map so we don't need a size variable 3 | }; 4 | 5 | TimeLimitedCache.prototype.set = function(key, value, duration) { 6 | let found = this.cache.has(key); 7 | if (found) clearTimeout(this.cache.get(key).ref); // Cancel previous timeout 8 | this.cache.set(key, { 9 | value, // Equivalent to `value: value` 10 | ref: setTimeout(() => this.cache.delete(key), duration) 11 | }); 12 | return found; 13 | }; 14 | 15 | TimeLimitedCache.prototype.get = function(key) { 16 | return this.cache.has(key) ? this.cache.get(key).value : -1; 17 | }; 18 | 19 | TimeLimitedCache.prototype.count = function() { 20 | return this.cache.size; 21 | }; -------------------------------------------------------------------------------- /Calculator with Method Chaining.js: -------------------------------------------------------------------------------- 1 | class Calculator { 2 | constructor(value) { 3 | this.result = value; 4 | } 5 | add(value) { 6 | this.result += value; 7 | return this; 8 | } 9 | 10 | subtract(value) { 11 | this.result -= value; 12 | return this; 13 | } 14 | 15 | multiply(value) { 16 | this.result *= value; 17 | return this; 18 | } 19 | 20 | divide(value) { 21 | if (value === 0) { 22 | throw new Error('Division by zero is not allowed'); 23 | } 24 | this.result /= value; 25 | return this; 26 | } 27 | 28 | power(value) { 29 | this.result = Math.pow(this.result, value); 30 | return this; 31 | } 32 | 33 | getResult() { 34 | return this.result; 35 | } 36 | } -------------------------------------------------------------------------------- /Chunk Array.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Array} arr 3 | * @param {number} size 4 | * @return {Array[]} 5 | */ 6 | var chunk = function (arr, size) { 7 | let result = [] 8 | for(i=0; i "Hello World"; 3 | }; -------------------------------------------------------------------------------- /Debounce.js: -------------------------------------------------------------------------------- 1 | var debounce = function(fn, t = 1000) { 2 | let timer; 3 | return function(...args) { 4 | clearTimeout(timer); 5 | timer = setTimeout(() => fn(...args), t); 6 | } 7 | }; -------------------------------------------------------------------------------- /Event Emitter.js: -------------------------------------------------------------------------------- 1 | class EventEmitter { 2 | constructor() { 3 | this.events = {}; 4 | } 5 | 6 | subscribe(eventName, callback) { 7 | if (!this.events[eventName]) { 8 | this.events[eventName] = []; 9 | } 10 | 11 | const eventListener = { callback }; 12 | this.events[eventName].push(eventListener); 13 | 14 | return { 15 | unsubscribe: () => { 16 | const index = this.events[eventName].indexOf(eventListener); 17 | if (index > -1) { 18 | this.events[eventName].splice(index, 1); 19 | return undefined; 20 | } 21 | } 22 | }; 23 | } 24 | 25 | emit(eventName, args = []) { 26 | const eventListeners = this.events[eventName]; 27 | if (!eventListeners) { 28 | return []; 29 | } 30 | 31 | return eventListeners.map((eventListener) => { 32 | return eventListener.callback(...args); 33 | }); 34 | } 35 | } -------------------------------------------------------------------------------- /Execute Asynchronous Functions in Parallel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Array} functions 3 | * @return {Promise} 4 | */ 5 | var promiseAll = async function(functions) { 6 | return new Promise((resolve, reject) => { 7 | // We know the resulting array will be the same length as functions 8 | const results = new Array(functions.length); 9 | let count = 0; 10 | functions.forEach((fn, i) => { 11 | fn() 12 | .then(val => { 13 | results[i] = val; 14 | count++; 15 | if(count === functions.length) resolve(results); 16 | }) 17 | .catch(reason => reject(reason)); 18 | }); 19 | }); 20 | }; 21 | 22 | /** 23 | * const promise = promiseAll([() => new Promise(res => res(42))]) 24 | * promise.then(console.log); // [42] 25 | */ -------------------------------------------------------------------------------- /Filter Elements from Array.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} arr 3 | * @param {Function} fn 4 | * @return {number[]} 5 | */ 6 | var filter = function(arr, fn) { 7 | var result = []; 8 | for (var i = 0; i < arr.length; i++) { 9 | if (fn(arr[i], i)) { 10 | result.push(arr[i]); 11 | } 12 | } 13 | return result; 14 | }; -------------------------------------------------------------------------------- /Flatten Deeply Nested Array.js: -------------------------------------------------------------------------------- 1 | var flat = function (arr, n, tempArray = [], currentCycle = 0) { 2 | for (let index = 0; index < arr.length; index++) { 3 | if (Array.isArray(arr[index]) && currentCycle < n) { 4 | flat(arr[index], n, tempArray, currentCycle + 1) 5 | } else { 6 | tempArray.push(arr[index]) 7 | } 8 | } 9 | return tempArray 10 | }; -------------------------------------------------------------------------------- /Function Composition.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Function[]} functions 3 | * @return {Function} 4 | */ 5 | var compose = function(functions) { 6 | if (functions.length === 0) { 7 | return function(x) { return x; }; 8 | } 9 | 10 | return functions.reduceRight(function(prevFn, nextFn) { 11 | return function(x) { 12 | return nextFn(prevFn(x)); 13 | }; 14 | }); 15 | 16 | }; 17 | 18 | 19 | const fn = compose([x => x + 1, x => 2 * x]); 20 | console.log(fn(4)); // 9 -------------------------------------------------------------------------------- /Group By.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Function} fn 3 | * @return {Object} 4 | */ 5 | Array.prototype.groupBy = function(fn) { 6 | return this.reduce((result, item) => { 7 | const key = fn(item); 8 | if (result.hasOwnProperty(key)) { 9 | result[key].push(item); 10 | } else { 11 | result[key] = [item]; 12 | } 13 | return result; 14 | }, {}); 15 | }; 16 | 17 | /** 18 | * [1,2,3].groupBy(String) // {"1":[1],"2":[2],"3":[3]} 19 | */ -------------------------------------------------------------------------------- /Interval Cancellation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Function} fn 3 | * @param {Array} args 4 | * @param {number} t 5 | * @return {Function} 6 | */ 7 | var cancellable = function(fn, args, t) { 8 | fn(...args); 9 | let timer = setInterval(()=> fn(...args),t); 10 | 11 | let cancelFn = () => clearInterval(timer) 12 | return cancelFn; 13 | }; 14 | 15 | /** 16 | * const result = [] 17 | * 18 | * const fn = (x) => x * 2 19 | * const args = [4], t = 35, cancelT = 190 20 | * 21 | * const start = performance.now() 22 | * 23 | * const log = (...argsArr) => { 24 | * const diff = Math.floor(performance.now() - start) 25 | * result.push({"time": diff, "returned": fn(...argsArr)}) 26 | * } 27 | * 28 | * const cancel = cancellable(log, args, t); 29 | * 30 | * setTimeout(() => { 31 | * cancel() 32 | * }, cancelT) 33 | * 34 | * setTimeout(() => { 35 | * console.log(result) // [ 36 | * // {"time":0,"returned":8}, 37 | * // {"time":35,"returned":8}, 38 | * // {"time":70,"returned":8}, 39 | * // {"time":105,"returned":8}, 40 | * // {"time":140,"returned":8}, 41 | * // {"time":175,"returned":8} 42 | * // ] 43 | * }, cancelT + t + 15) 44 | */ -------------------------------------------------------------------------------- /Is Object Empty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Object|Array} obj 3 | * @return {boolean} 4 | */ 5 | function isEmpty(input) { 6 | // Check for object 7 | if (typeof input === 'object' && !Array.isArray(input)) { 8 | return Object.keys(input).length === 0; 9 | } 10 | 11 | // Check for array 12 | if (Array.isArray(input)) { 13 | return input.length === 0; 14 | } 15 | 16 | // Other data types are not considered empty 17 | return false; 18 | } -------------------------------------------------------------------------------- /Join Two Arrays by ID.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Array} arr1 3 | * @param {Array} arr2 4 | * @return {Array} 5 | */ 6 | var join = function(arr1, arr2) { 7 | const result = {}; 8 | for (let i = 0; i < arr1.length; i++) { 9 | result[arr1[i].id] = arr1[i]; 10 | } 11 | for (let i = 0; i < arr2.length; i++) { 12 | if (result[arr2[i].id]) { 13 | for (const key in arr2[i]) result[arr2[i].id][key] = arr2[i][key]; 14 | } else { 15 | result[arr2[i].id] = arr2[i]; 16 | } 17 | } 18 | 19 | return Object.values(result); 20 | }; -------------------------------------------------------------------------------- /Memoize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Function} fn 3 | * @return {Function} 4 | */ 5 | function memoize(fn) { 6 | let map = {}; 7 | return function(...args) { 8 | const s = args.toString(); 9 | if(s in map){ 10 | return map[s]; 11 | }else{ 12 | let res = fn(...args); 13 | map[s] = res; 14 | return res; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Promise Time Limit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Function} fn 3 | * @param {number} t 4 | * @return {Function} 5 | */ 6 | var timeLimit = function(fn, t) { 7 | return async function(...args) { 8 | const originalFnPromise = fn(...args); 9 | 10 | const timeoutPromise = new Promise((_, reject) => { 11 | setTimeout(() => { 12 | reject('Time Limit Exceeded') 13 | }, t); 14 | }) 15 | 16 | return Promise.race([originalFnPromise, timeoutPromise]); 17 | } 18 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaScript -------------------------------------------------------------------------------- /Return Length of Arguments Passed.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {...(null|boolean|number|string|Array|Object)} args 3 | * @return {number} 4 | */ 5 | var argumentsLength = function(...args) { 6 | return args.length; 7 | }; -------------------------------------------------------------------------------- /Sleep.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} millis 3 | */ 4 | async function sleep(millis) { 5 | await new Promise(resolve => setTimeout(resolve, millis)); 6 | } 7 | 8 | /** 9 | * let t = Date.now() 10 | * sleep(100).then(() => console.log(Date.now() - t)) // 100 11 | */ -------------------------------------------------------------------------------- /Sort By.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Array} arr 3 | * @param {Function} fn 4 | * @return {Array} 5 | */// merge sort 6 | var sortBy = function(arr, fn) { 7 | const n = arr.length; 8 | // base case 9 | if (n == 1) return arr; 10 | 11 | // divide 12 | const mid = Math.floor(n/2); 13 | const arrLeft = arr.slice(0, mid); 14 | const arrRight = arr.slice(mid, n); 15 | 16 | // sort and merge 17 | return merge(sortBy(arrLeft, fn), sortBy(arrRight, fn), fn); 18 | }; 19 | 20 | /** 21 | * @param {Array} left 22 | * @param {Array} right 23 | * @param {Function} fn 24 | * @return {Array} 25 | */// merge function 26 | function merge (left, right, fn) { 27 | const sortedArray = []; 28 | while (left.length > 0 && right.length > 0) { 29 | // sort and merge 30 | if (fn(left[0]) < fn(right[0])) { 31 | sortedArray.push(left[0]); 32 | left.shift(); 33 | } else { 34 | sortedArray.push(right[0]); 35 | right.shift(); 36 | } 37 | } 38 | 39 | return sortedArray.concat(left, right); 40 | } -------------------------------------------------------------------------------- /Timeout Cancellation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Function} fn 3 | * @param {Array} args 4 | * @param {number} t 5 | * @return {Function} 6 | */ 7 | const cancellable = function(fn, args, t) { 8 | // cancelFn function// 9 | const cancelFn = function (){ 10 | clearTimeout(timer); 11 | }; 12 | const timer = setTimeout(()=>{ 13 | fn(...args) 14 | }, t); 15 | return cancelFn ; 16 | }; 17 | 18 | 19 | /** 20 | * const result = [] 21 | * 22 | * const fn = (x) => x * 5 23 | * const args = [2], t = 20, cancelT = 50 24 | * 25 | * const log = (...argsArr) => { 26 | * result.push(fn(...argsArr)) 27 | * } 28 | * 29 | * const cancel = cancellable(fn, args, t); 30 | * 31 | * setTimeout(() => { 32 | * cancel() 33 | * console.log(result) // [{"time":20,"returned":10}] 34 | * }, cancelT) 35 | */ -------------------------------------------------------------------------------- /To Be Or Not To Be.js: -------------------------------------------------------------------------------- 1 | var expect = function(val) { 2 | return { 3 | toBe: (val2) => { 4 | if (val !== val2) throw new Error("Not Equal"); 5 | else return true; 6 | }, 7 | notToBe: (val2) => { 8 | if (val === val2) throw new Error("Equal"); 9 | else return true; 10 | } 11 | } 12 | }; 13 | --------------------------------------------------------------------------------