├── index.js ├── DSA ├── largeSmallString.js ├── rotateString.js ├── nonRepeatedNumber.js ├── runningFrequencies.js ├── commonSubstrings.js ├── stringPangram.js ├── arraySubset.js ├── reverseStringGivenParameter.js ├── deleteDuplicates.js ├── array2DSpiral.js ├── LRUCache.js ├── maxStack.js └── stackBalancedParanthesis.js ├── .gitignore ├── string-utilities ├── reverseString.js ├── stringSplit.js ├── stringReplace.js └── stringCasing.js ├── webAPIs ├── setTimeoutOutput.js ├── nestedSetTimeout.js ├── timeBombSetInterval.js └── callAfterDelayCumulative.js ├── promises ├── fakeFetch.js ├── myPromiseRace.js ├── myPromiseAllSync.js ├── myFunctionWrapper.js ├── myPromiseAny.js ├── myPromiseAll.js └── promises.js ├── arrayTraversal ├── arrayZip.js ├── reduceExamples.js ├── flattenArrayUsingReduce.js └── reduceCurrying.js ├── lodash-utilities ├── once.js ├── delay.js ├── curry.js ├── assign.js ├── debounce.js ├── memoize.js ├── throttle.js ├── cloneDeep.js └── cloneDeepWithCircularDependency.js ├── polyfills ├── myFind.js ├── myCall.js ├── myMap.js ├── myApply.js ├── myFilter.js ├── myBind.js ├── myReduce.js └── myPromise.js ├── react-snippets ├── event-delegation │ ├── README.md │ └── src │ │ ├── styles.css │ │ └── App.js └── timer.js ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ └── codeql-analysis.yml ├── js-coding-questions ├── sampleCSV.csv ├── readCSVFile.js ├── findObjectPath.js └── groupBy.js ├── vanillaJs └── toast-notification │ ├── README.md │ ├── index.html │ └── src │ ├── styles.css │ └── index.js ├── package.json ├── recursion ├── redditComment.js ├── flattenObject.js ├── zigZagSpiralTraversal.js ├── flattenArray.js ├── arrayToList.js └── binarySearchTree.js ├── react-custom-hooks ├── useThrottle.js ├── useDebounce.js ├── useMemo.js └── useCallback.js ├── patterns └── pubSub.js ├── LICENSE ├── currying └── infiniteCurrying.js ├── ObjectOrientedJS └── objectsInDepth.js ├── README.md ├── CODE_OF_CONDUCT.md └── CONTRIBUTING.md /index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /DSA/largeSmallString.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | **/package.json 3 | **/.codesandbox 4 | /node_modules -------------------------------------------------------------------------------- /string-utilities/reverseString.js: -------------------------------------------------------------------------------- 1 | const str = "JavaScript is awesome" 2 | let reversedString = ""; 3 | for(let i = 0; i < str.length; i++){ 4 | reversedString = str.charAt(i) + reversedString; 5 | } 6 | 7 | console.log(reversedString); -------------------------------------------------------------------------------- /webAPIs/setTimeoutOutput.js: -------------------------------------------------------------------------------- 1 | // this inside setTimeout 2 | const obj = { 3 | type:'poster', 4 | logger: function () { 5 | setTimeout(function () { 6 | console.log(this.type); 7 | }, 1000); 8 | } 9 | } 10 | 11 | obj.logger(); -------------------------------------------------------------------------------- /DSA/rotateString.js: -------------------------------------------------------------------------------- 1 | function rotateString(string, number) { 2 | let rightLimit = number % string.length; 3 | let leftString = string.slice(-rightLimit); 4 | return leftString + string.slice(0, string.length - rightLimit); 5 | } 6 | 7 | console.log(rotateString("KaranZ", 3)); -------------------------------------------------------------------------------- /DSA/nonRepeatedNumber.js: -------------------------------------------------------------------------------- 1 | const array = [1, 3, 5, 4, 2, 4]; 2 | 3 | function findNonRepeatedNumber(arr) { 4 | let result = 0; 5 | for (let index in array) { 6 | result ^= arr[index] ^ index; 7 | } 8 | return result; 9 | } 10 | 11 | console.log(findNonRepeatedNumber(array)); -------------------------------------------------------------------------------- /webAPIs/nestedSetTimeout.js: -------------------------------------------------------------------------------- 1 | function printNumbers(from, to, delay) { 2 | let start = from; 3 | setTimeout(function printNumber() { 4 | console.log(start); 5 | if (start < to) { 6 | setTimeout(printNumber, delay * 1000); 7 | } 8 | start++; 9 | }); 10 | } 11 | 12 | printNumbers(1, 10, 1); -------------------------------------------------------------------------------- /promises/fakeFetch.js: -------------------------------------------------------------------------------- 1 | const fakeFetch = (paramter) => { 2 | return new Promise((resolve, reject) => { 3 | setTimeout(() => { 4 | paramter ? resolve("promise resolved") : reject('promise rejected!') 5 | }, 3000) 6 | }) 7 | } 8 | 9 | fakeFetch(true).then((value) => console.log(value)).catch(err => console.error(err)); -------------------------------------------------------------------------------- /webAPIs/timeBombSetInterval.js: -------------------------------------------------------------------------------- 1 | function timeBomb(from, delay) { 2 | let start = from; 3 | const id = setInterval(() => { 4 | if (start === 0) { 5 | console.log("Time Over!"); 6 | return clearInterval(id); 7 | } 8 | console.log(start); 9 | start--; 10 | }, delay * 1000); 11 | } 12 | 13 | timeBomb(10, 1); -------------------------------------------------------------------------------- /arrayTraversal/arrayZip.js: -------------------------------------------------------------------------------- 1 | function zip(arr1, arr2) { 2 | const maxLength = Math.max(arr1.length, arr2.length); 3 | const resultArray = new Array(maxLength).fill().map((_, index) => [arr1[index], arr2[index]]); 4 | return resultArray; 5 | } 6 | 7 | const arr1 = [1, 4, 1, 1, 88, 9]; 8 | 9 | const arr2 = [18, 22, 50, 6]; 10 | 11 | console.log(zip(arr1, arr2)); 12 | -------------------------------------------------------------------------------- /webAPIs/callAfterDelayCumulative.js: -------------------------------------------------------------------------------- 1 | function callAfterDelay(array) { 2 | let interval = 0; 3 | array.forEach((element) => { 4 | interval += element; 5 | setTimeout(() => { 6 | console.log(element); 7 | }, interval * 1000); 8 | }); 9 | } 10 | 11 | const array = [1, 4, 8, 2, 5, 3]; 12 | // const array = [1, 22, 11, 5]; 13 | 14 | callAfterDelay(array); -------------------------------------------------------------------------------- /lodash-utilities/once.js: -------------------------------------------------------------------------------- 1 | function callMeOnce(fn) { 2 | const context = this; 3 | let called = false; 4 | return function (...args) { 5 | if (called) { 6 | return; 7 | } 8 | called = true; 9 | return fn.apply(context, args); 10 | }; 11 | } 12 | 13 | const printText = () => console.log("Called!"); 14 | 15 | const once = callMeOnce(printText); 16 | 17 | once(); 18 | once(); 19 | once(); 20 | once(); -------------------------------------------------------------------------------- /polyfills/myFind.js: -------------------------------------------------------------------------------- 1 | // ------------------- Find Polyfill ---------------------- 2 | 3 | function myFind(callback, thisArg){ 4 | for(let i = 0; i < this.length; i++){ 5 | if(callback.call(thisArg || this, this[i], i, this)){ 6 | return this[i]; 7 | } 8 | } 9 | } 10 | 11 | Array.prototype.myFind = myFind; 12 | 13 | const array = [5, 12, 8, 130, 44]; 14 | 15 | console.log(array.find(element => element > 10)); -------------------------------------------------------------------------------- /lodash-utilities/delay.js: -------------------------------------------------------------------------------- 1 | function delay(func, delay, ...args) { 2 | const context = this; 3 | setTimeout(() => { 4 | func.apply(context, args); 5 | }) 6 | } 7 | 8 | const printText = function() { 9 | console.log(`Hi I'm ${this.name}`); 10 | } 11 | 12 | delay(printText, 2000); 13 | 14 | const myself = { 15 | name: 'Jaynil', 16 | intro: function() { 17 | delay.call(this, printText, 3000); 18 | } 19 | }; 20 | 21 | myself.intro(); 22 | -------------------------------------------------------------------------------- /polyfills/myCall.js: -------------------------------------------------------------------------------- 1 | // ------------------- Call Polyfill ---------------------- 2 | 3 | const brother = { 4 | name: 'Jaynil', 5 | intro: function() { 6 | console.log(`Hello, ${this.name}`) 7 | } 8 | } 9 | 10 | const sister = { 11 | name: 'Nishi', 12 | }; 13 | 14 | function myCall(thisArg, ...args) { 15 | thisArg.fn = this; 16 | return thisArg.fn(...args); 17 | } 18 | 19 | Function.prototype.myCall = myCall; 20 | 21 | brother.intro.myCall(sister); -------------------------------------------------------------------------------- /DSA/runningFrequencies.js: -------------------------------------------------------------------------------- 1 | function findRunningFrequencies(string) { 2 | if (!string) { 3 | return string; 4 | } 5 | let resultString = ""; 6 | let count = 1; 7 | for (let i = 1; i <= string.length; i++) { 8 | if (string[i] === string[i - 1]) { 9 | count += 1; 10 | } else { 11 | resultString += string[i - 1] + count; 12 | count = 1; 13 | } 14 | } 15 | return resultString; 16 | } 17 | 18 | console.log(findRunningFrequencies("1111333")); -------------------------------------------------------------------------------- /lodash-utilities/curry.js: -------------------------------------------------------------------------------- 1 | function curry(func) { 2 | return function recursiveCurry(...args) { 3 | if (args.length >= func.length) { 4 | return func.apply(this, args); 5 | } 6 | return recursiveCurry.bind(this, ...args) 7 | } 8 | } 9 | 10 | function getMultiplication(a, b, c, d) { 11 | return a * b * c * d; 12 | } 13 | 14 | const curriedMul = curry(getMultiplication); 15 | 16 | console.log(curriedMul(2)(3)(4, 1)); 17 | 18 | console.log(curriedMul(2)(3)(4)(1)); -------------------------------------------------------------------------------- /polyfills/myMap.js: -------------------------------------------------------------------------------- 1 | // ------------------- Map Polyfill ---------------------- 2 | 3 | const array = [1, 4, 9, 16, 25]; 4 | 5 | function myMap(callback) { 6 | const tempArray = []; 7 | for (let i = 0; i < this.length; i++) { 8 | tempArray.push(callback.call(this, this[i], i)); 9 | } 10 | return tempArray; 11 | } 12 | 13 | Array.prototype.myMap = myMap; 14 | 15 | const result = array.myMap((item) => { 16 | return item * item; 17 | }); 18 | 19 | console.log(result); 20 | -------------------------------------------------------------------------------- /string-utilities/stringSplit.js: -------------------------------------------------------------------------------- 1 | const string = 'Javascript is awesome!'; 2 | 3 | function mySplit(string, separator) { 4 | const resultArray = []; 5 | let word = ""; 6 | for (let i = 0; i < string.length; i++) { 7 | if (string[i] !== separator) { 8 | word += string[i]; 9 | } else { 10 | resultArray.push(word); 11 | word = ""; 12 | } 13 | } 14 | resultArray.push(word); 15 | return resultArray; 16 | } 17 | 18 | console.log(mySplit(string, " ")); -------------------------------------------------------------------------------- /polyfills/myApply.js: -------------------------------------------------------------------------------- 1 | // ------------------- Apply Polyfill ---------------------- 2 | 3 | const brother = { 4 | name: 'Jaynil', 5 | intro: function() { 6 | console.log(`Hello, ${this.name}`) 7 | } 8 | } 9 | 10 | const sister = { 11 | name: 'Nishi', 12 | }; 13 | 14 | function myApply(thisArg, args) { 15 | thisArg.fn = this; 16 | return args ? thisArg.fn(...args) : thisArg.fn(); 17 | } 18 | 19 | Function.prototype.myApply = myApply; 20 | 21 | brother.intro.myApply(sister); -------------------------------------------------------------------------------- /polyfills/myFilter.js: -------------------------------------------------------------------------------- 1 | // ------------------- Filter Polyfill ---------------------- 2 | 3 | function myFilter(callback){ 4 | let filteredArray = []; 5 | for(let i = 0; i < this.length; i++){ 6 | if(callback.call(this, this[i], i, this)){ 7 | filteredArray.push(this[i]); 8 | } 9 | } 10 | return filteredArray; 11 | } 12 | 13 | Array.prototype.myFilter = myFilter; 14 | 15 | const array = [1, 2, 3, 4, 5]; 16 | 17 | console.log(array.myFilter((value) => !(value & 1))); -------------------------------------------------------------------------------- /DSA/commonSubstrings.js: -------------------------------------------------------------------------------- 1 | const string1 = 'HI'; 2 | const string2 = 'ALL'; 3 | 4 | function findCommonString(str1, str2) { 5 | const stringMap = new Map(); 6 | let resultString = ''; 7 | for (let char of str1) { 8 | stringMap[char] = true; 9 | } 10 | 11 | for (let char of str2) { 12 | if (stringMap[char]) { 13 | resultString += char 14 | } 15 | } 16 | return resultString.length > 0 ? resultString : false; 17 | } 18 | 19 | console.log(findCommonString(string1, string2)); -------------------------------------------------------------------------------- /DSA/stringPangram.js: -------------------------------------------------------------------------------- 1 | const string = "A quick brown fox jumps over the little lazy dog"; 2 | 3 | const checkPangram = (string) => { 4 | const characterArray = Array(26).fill(false); 5 | for (let i = 0; i < string.length; i++) { 6 | const value = string[i].toLowerCase().charCodeAt(0) - 97; 7 | characterArray[value] = true; 8 | } 9 | return characterArray.reduce((result, value) => { 10 | return result && value; 11 | }, true); 12 | }; 13 | 14 | console.log(checkPangram(string)); 15 | -------------------------------------------------------------------------------- /lodash-utilities/assign.js: -------------------------------------------------------------------------------- 1 | function assign(targetObj, ...sourceObjects) { 2 | return sourceObjects.reduce((finalObj, currentObj) => { 3 | return { ...finalObj, ...currentObj } 4 | }, targetObj); 5 | } 6 | 7 | const duck = { 8 | hasBill: true, 9 | feet: 'orange' 10 | }; 11 | 12 | const beaver = { 13 | hasTail: true 14 | }; 15 | 16 | const otter = { 17 | hasFur: true, 18 | feet: 'webbed' 19 | }; 20 | 21 | const result = assign({}, duck, beaver, otter); 22 | 23 | console.log(result); -------------------------------------------------------------------------------- /react-snippets/event-delegation/README.md: -------------------------------------------------------------------------------- 1 | ## Question Description 2 | 3 | Render the movie data similar to following: 4 | 5 | ![Table](https://raw.githubusercontent.com/manmodesanket/content-archives/main/screenshot.png) 6 | 7 | After clicking on each cell an alert dialog should popup with respective movie data. 8 | 9 | If user clicks on "Imdb Ratings" then an alert dialog should popup with movie rating. 10 | 11 | ## Solution 12 | 13 | Event Delegation Solution [link](https://codesandbox.io/s/bubbling-problem-8erwc). -------------------------------------------------------------------------------- /arrayTraversal/reduceExamples.js: -------------------------------------------------------------------------------- 1 | // Find the number of strings with similar number of characters . 2 | 3 | const inputArray = ["apple", "orange", "mango", "papaya", "banana", "pomegranate"]; 4 | 5 | const stringMapping = inputArray.reduce((lengthToStringMap, inputString) => { 6 | const stringLength = inputString.length; 7 | if (stringLength in lengthToStringMap) { 8 | lengthToStringMap[stringLength] += 1 9 | } else { 10 | lengthToStringMap[stringLength] = 1 11 | } 12 | return lengthToStringMap; 13 | }, {}); 14 | 15 | console.log(stringMapping); -------------------------------------------------------------------------------- /polyfills/myBind.js: -------------------------------------------------------------------------------- 1 | // ------------------- Bind Polyfill ---------------------- 2 | 3 | const brother = { 4 | name: 'Jaynil', 5 | intro: function() { 6 | console.log(`Hello, ${this.name}`) 7 | } 8 | } 9 | 10 | const sister = { 11 | name: 'Nishi', 12 | }; 13 | 14 | function myBind(thisArg, ...parameters) { 15 | const functionToBeCalled = this; 16 | return function() { 17 | return functionToBeCalled.apply(thisArg, parameters); 18 | } 19 | } 20 | 21 | Function.prototype.myBind = myBind; 22 | 23 | const sisterIntro = brother.intro.myBind(sister); 24 | sisterIntro(); -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **Expected behavior** 13 | A clear and concise description of what you expected to happen. 14 | 15 | **Screenshots / Live demo link (paste the github-readme-stats link as markdown image)** 16 | If applicable, add screenshots to help explain your problem. 17 | 18 | **Additional context** 19 | Add any other context about the problem here. -------------------------------------------------------------------------------- /lodash-utilities/debounce.js: -------------------------------------------------------------------------------- 1 | function debounce(func, delay) { 2 | let timer = ""; 3 | return function() { 4 | const context = this; 5 | clearTimeout(timer); 6 | timer = setTimeout(() => func.apply(context, arguments), delay); 7 | } 8 | } 9 | 10 | const printText = function() { 11 | console.log(`Hello, I'm ${this.name}`) 12 | } 13 | 14 | const debouncedFunc = debounce(printText, 4000); 15 | 16 | debouncedFunc(); // this is undefined 17 | 18 | const myself = { 19 | name: 'Jaynil', 20 | intro: debounce(printText, 3000) 21 | }; 22 | 23 | myself.intro(); // this is myself object -------------------------------------------------------------------------------- /js-coding-questions/sampleCSV.csv: -------------------------------------------------------------------------------- 1 | State,Suburb,2019 ERP population,% Vaccinated - Dose 1,% Vaccinated - Dose 2 2 | New South Wales,Albury,"52,067",>95%,>95% 3 | New South Wales,Armidale,"31,679",92.4%,88.9% 4 | New South Wales,Auburn,"86,994",94.1%,91.0% 5 | New South Wales,Bankstown,"147,237",93.3%,89.9% 6 | New South Wales,Bathurst,"39,532",>95%,93.0% 7 | New South Wales,Baulkham Hills,"124,066",>95%,>95% 8 | New South Wales,Blacktown,"115,631",>95%,>95% 9 | New South Wales,Blacktown - North,"85,385",>95%,>95% 10 | New South Wales,Blue Mountains,"64,747",>95%,>95% 11 | New South Wales,Botany,"45,823",>95%,>95% -------------------------------------------------------------------------------- /vanillaJs/toast-notification/README.md: -------------------------------------------------------------------------------- 1 | ## Toast Notification 2 | 3 | Q. Upon clicking Info button and Warning button toast notification should popup at the bottom of the screen and if Error button is clicked error notification should popup at the top of screen. 4 | 5 | This problem tests css skills as well as knowledge of JavaScript DOM APIs. It is not expected to know all DOM APIs, feel free to ask for help. 6 | 7 | This can be enhanced more. Further, you can add a close button on the toast notification which closes the toast. 8 | 9 | ## Solution 10 | 11 | Toast Notification Solution [link](https://codesandbox.io/s/toast-notification-h6cut) -------------------------------------------------------------------------------- /DSA/arraySubset.js: -------------------------------------------------------------------------------- 1 | const arr1 = [1, 3, 5, 2, 0, 7]; 2 | const arr2 = [3, 2, 0]; 3 | 4 | // subset of arrays in order 5 | const checkArraySubset = (arr1, arr2) => { 6 | const arr1Values = new Map(); 7 | arr1.map((value, index) => (arr1Values[value] = index)); 8 | 9 | let result = true; 10 | for (let i = 1; i <= arr2.length; i++) { 11 | if (arr1Values[arr2[i - 1]] > arr1Values[arr2[i]]) { 12 | result = false; 13 | } 14 | } 15 | return result; 16 | }; 17 | 18 | console.log(checkArraySubset(arr1, arr2)); 19 | // Avoid use of in-built array functions like sort, filter, etc 20 | // Check before using them with the interviewer 21 | -------------------------------------------------------------------------------- /react-snippets/event-delegation/src/styles.css: -------------------------------------------------------------------------------- 1 | .App { 2 | font-family: sans-serif; 3 | text-align: center; 4 | } 5 | 6 | .row { 7 | display: grid; 8 | grid-template-columns: 1fr 1fr 1fr; 9 | cursor: pointer; 10 | } 11 | 12 | .row__item { 13 | border: 1px solid black; 14 | padding: 1rem; 15 | } 16 | 17 | .item__charac { 18 | background-color: orange; 19 | } 20 | 21 | .item__movie { 22 | background-color: yellow; 23 | } 24 | 25 | .item__rating { 26 | background-color: skyblue; 27 | } 28 | 29 | .rating { 30 | padding: 0.5rem; 31 | background-color: green; 32 | border: 1px slolid green; 33 | border-radius: 25px; 34 | } 35 | -------------------------------------------------------------------------------- /promises/myPromiseRace.js: -------------------------------------------------------------------------------- 1 | const fakeFetch = (paramter, delay, value) => { 2 | return new Promise((resolve, reject) => { 3 | setTimeout(() => { 4 | paramter ? resolve(value) : reject(`Promise rejected! ${value}`) 5 | }, delay) 6 | }) 7 | } 8 | 9 | function myPromiseRace(promises) { 10 | return new Promise((resolve, reject) => { 11 | promises.forEach(async (promise) => { 12 | try { 13 | const output = await promise; 14 | resolve(output); 15 | } catch (err) { 16 | reject(err); 17 | } 18 | }) 19 | }) 20 | }; 21 | 22 | myPromiseRace([fakeFetch(true, 1000, 'p1'), fakeFetch(true, 500, 'p2')]).then(results => console.log(results)); -------------------------------------------------------------------------------- /DSA/reverseStringGivenParameter.js: -------------------------------------------------------------------------------- 1 | function reverse(string) { 2 | let result = ""; 3 | for (let i = 0; i < string.length; i++) { 4 | result = string[i] + result; 5 | } 6 | return result; 7 | } 8 | 9 | function reverseString(string, k) { 10 | if (string.length <= k) { 11 | return reverse(string); 12 | } 13 | let left = 0, 14 | right = k, 15 | result = ""; 16 | while (right < string.length) { 17 | result += reverse(string.substring(left, right)); 18 | right += k; 19 | left += k; 20 | } 21 | result += reverse(string.substring(left)); 22 | return result; 23 | } 24 | 25 | console.log(reverseString("abcdefgh", 3)); 26 | console.log(reverseString("abcdefghi", 4)); -------------------------------------------------------------------------------- /lodash-utilities/memoize.js: -------------------------------------------------------------------------------- 1 | function memoize(func, resolver) { 2 | const cache = {}; 3 | return function() { 4 | const context = this; 5 | const args = arguments; 6 | const key = resolver ? resolver(...args) : args[0]; 7 | if (!cache[key]) { 8 | cache[key] = func.apply(context, args); 9 | } 10 | return cache[key]; 11 | } 12 | } 13 | 14 | function summation(n) { 15 | return n < 1 ? n : n + summation(n - 1); 16 | } 17 | 18 | const resolver = (n) => `%${n}%`; 19 | 20 | const memoizedSummation = memoize(summation, resolver); 21 | 22 | console.log(memoizedSummation(60)); 23 | 24 | // This time the whole summation process wouldn't be repeated as it's present in cache 25 | console.log(memoizedSummation(60)); -------------------------------------------------------------------------------- /arrayTraversal/flattenArrayUsingReduce.js: -------------------------------------------------------------------------------- 1 | const array = [ 2 | 1, 2, 3, 3 | [4], 4 | [5, 6, [7], [8, [9, [10]]]], 5 | 11, 12, 13, 6 | [14, [[[[[15, [16]]]]]]], 7 | 17, 18, 8 | [19, [20, [21, [22, [23, [24, [[[[[25]]]]]]]]]]] 9 | ]; 10 | 11 | function flatten(depth = 1) { 12 | function flattenedArray(arr, d) { 13 | return arr.reduce((result, currentValue) => { 14 | if (d > 0) { 15 | return result.concat(Array.isArray(currentValue) ? flattenedArray(currentValue, d - 1) : currentValue) 16 | } 17 | result.push(currentValue) 18 | return result; 19 | }, []); 20 | } 21 | return flattenedArray(this, depth); 22 | } 23 | 24 | Array.prototype.flatten = flatten; 25 | 26 | console.log(JSON.stringify(array.flatten(15))); -------------------------------------------------------------------------------- /DSA/deleteDuplicates.js: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array containing all kinds of data, implement a function deduplicate() to remove the duplicates. You should modify the array in place. 3 | */ 4 | 5 | function removeDuplicates(arr) { 6 | const hashmap = new Map(); 7 | let left = 0, 8 | right = arr.length - 1; 9 | while (left <= right) { 10 | const key = JSON.stringify(arr[left]); 11 | if (hashmap[key]) { 12 | [arr[left], arr[right]] = [arr[right], arr[left]]; 13 | right -= 1; 14 | } else { 15 | hashmap[key] = true; 16 | left += 1; 17 | } 18 | } 19 | arr.splice(right + 1); 20 | return arr; 21 | } 22 | 23 | console.log(removeDuplicates([1, 2, 3, 3, 4, { a: 5 }, { a: 5 }])); 24 | // Getting the requirements of all kinds of data -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MockInterview-1", 3 | "version": "1.0.0", 4 | "description": "This repository contains the javascript interview preparation questions & solutions.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Jaynil1611/Javascript-Interview-Preparation.git" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/Jaynil1611/Javascript-Interview-Preparation/issues" 18 | }, 19 | "homepage": "https://github.com/Jaynil1611/Javascript-Interview-Preparation#readme", 20 | "dependencies": { 21 | "react": "^17.0.2" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /vanillaJs/toast-notification/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Parcel Sandbox 5 | 6 | 7 | 8 | 9 |
10 |
11 | 12 | 15 | 18 |
19 |
20 |
21 |
22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /lodash-utilities/throttle.js: -------------------------------------------------------------------------------- 1 | function throttle(func, delay) { 2 | let flag = true; 3 | return function() { 4 | let context = this, args = arguments; 5 | if (flag) { 6 | flag = false; 7 | func.apply(context, args); 8 | setTimeout(() => flag = true, delay); 9 | } 10 | } 11 | } 12 | 13 | const printText = function() { 14 | console.log(`Hi, I'm ${this.name || 'logger'}`); 15 | } 16 | 17 | const throttled = throttle(printText, 2000); 18 | 19 | console.log("Test One"); 20 | throttled(); 21 | throttled(); 22 | throttled(); 23 | throttled(); 24 | setTimeout(throttled, 2000); 25 | 26 | const myself = { 27 | name: 'Jaynil', 28 | intro: throttle(printText, 2000) 29 | }; 30 | 31 | console.log("Test Two"); 32 | setTimeout(() => myself.intro(), 2000); 33 | -------------------------------------------------------------------------------- /recursion/redditComment.js: -------------------------------------------------------------------------------- 1 | // sample data for reddit comments (flatened list of comments connected by parent_id) 2 | const flatenedComments = [ 3 | { 4 | id: 1, 5 | parent_id: null, 6 | }, 7 | { 8 | id: 2, 9 | parent_id: null, 10 | }, 11 | { 12 | id: 3, 13 | parent_id: 1, 14 | }, 15 | { 16 | id: 4, 17 | parent_id: 2, 18 | }, 19 | { 20 | id: 5, 21 | parent_id: 4, 22 | } 23 | ]; 24 | 25 | const getComments = (commentsList, parentId = null) => 26 | commentsList 27 | .filter(comment => comment.parent_id === parentId) 28 | .map(comment => ({ ...comment, children: getComments(commentsList, comment.id) })) 29 | 30 | 31 | const nestedComments = getComments(flatenedComments); 32 | 33 | console.log(JSON.stringify(nestedComments)); -------------------------------------------------------------------------------- /react-custom-hooks/useThrottle.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import "./styles.css"; 3 | 4 | const useThrottle = (func, delay) => { 5 | const [flag, setFlag] = useState(true); 6 | 7 | return function () { 8 | let args = arguments, 9 | context = this; 10 | if (flag) { 11 | func.apply(context, args); 12 | setTimeout(() => setFlag(true), delay); 13 | setFlag(false); 14 | } 15 | }; 16 | }; 17 | 18 | const Throttle = () => { 19 | const printText = () => console.log("Logger"); 20 | const throttledLogger = useThrottle(printText, 3000); 21 | 22 | return ( 23 |
24 | 25 |
26 | ); 27 | }; 28 | 29 | export default function App() { 30 | return ; 31 | } 32 | -------------------------------------------------------------------------------- /polyfills/myReduce.js: -------------------------------------------------------------------------------- 1 | // ------------------- Reduce Polyfill ---------------------- 2 | 3 | function myReduce(callback, initialValue) { 4 | const argumentsLength = arguments.length; 5 | if (!this.length) { 6 | return argumentsLength > 1 ? initialValue : new TypeError('Reduce of empty array with no initial value'); 7 | } 8 | 9 | let i = 0; 10 | let accumulator = initialValue; 11 | if (argumentsLength < 2) { 12 | accumulator = this[0] 13 | i = 1; 14 | } 15 | while (i < this.length) { 16 | accumulator = callback.call(this, accumulator, this[i], i, this); 17 | i++; 18 | } 19 | return accumulator; 20 | } 21 | 22 | Array.prototype.myReduce = myReduce; 23 | 24 | const result = [1, 2, 3, 4].myReduce((sum, value) => { 25 | return sum + value; 26 | }, 1) 27 | 28 | console.log(result); -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | Description of the question you're suggesting to add to this repository 3 | 4 | ## Type 5 | Describe the type of question 6 | e.g. Objective, Subjective, Machine Coding, etc. 7 | 8 | ## Related Technology 9 | Specify the related web technology 10 | e.g. HTML, CSS, JavaScript, TypeScript, React, etc. 11 | 12 | ## Source 13 | If possible, add source of the question. 14 | Answer these questions to identify the source: 15 | - Where did you find this question? 16 | - Was this question asked in real interviews? 17 | - Which company or type of companies ask this type of question 18 | 19 | ## Working Solution 20 | If have a working solution ready, attach a link to the solution which can be reviewed easily. 21 | Otherwise ignore this part. 22 | 23 | ## Credits 24 | Give credits for the question -------------------------------------------------------------------------------- /recursion/flattenObject.js: -------------------------------------------------------------------------------- 1 | const user = { 2 | name: "Akshay Saini", 3 | address: { 4 | personal: { 5 | city: "Dehradun", 6 | state: "Uttrakhand", 7 | area: "Majra", 8 | }, 9 | office: { 10 | city: "Hyderabad", 11 | area: { 12 | landmark: "Hi Tech", 13 | } 14 | } 15 | } 16 | }; 17 | 18 | function flattenObject(sourceObject, targetObject, key) { 19 | return Object.keys(sourceObject).reduce((finalObject, currentKey) => { 20 | if (typeof sourceObject[currentKey] !== 'object') { 21 | return { ...finalObject, [`${key}_${currentKey}`]: sourceObject[currentKey] }; 22 | } 23 | return { ...finalObject, ...flattenObject(sourceObject[currentKey], finalObject, `${key}_${currentKey}`) }; 24 | }, targetObject); 25 | } 26 | 27 | console.log(flattenObject(user, {}, 'user')); -------------------------------------------------------------------------------- /arrayTraversal/reduceCurrying.js: -------------------------------------------------------------------------------- 1 | function compose(...functions) { 2 | return function(argument, delay) { 3 | return new Promise((resolve, reject) => { 4 | try { 5 | setTimeout(() => { 6 | const result = functions.reduce((result, func) => { 7 | return func.call(func, result); 8 | }, argument); 9 | resolve(result); 10 | }, delay * 1000); 11 | } catch (err) { 12 | reject(err); 13 | } 14 | }); 15 | } 16 | } 17 | 18 | const square = (x) => x*x; 19 | 20 | const mutiplyBy3 = (x) => x*3 ; 21 | 22 | const divideBy2 = (x) => x/2; 23 | 24 | const convertToString = (x) => x+""; 25 | 26 | const arrayOfFunctions = [square,mutiplyBy3,divideBy2,convertToString]; 27 | 28 | const composeUtil = compose(...arrayOfFunctions); 29 | 30 | composeUtil(4, 4).then((res) => console.log(res)); -------------------------------------------------------------------------------- /promises/myPromiseAllSync.js: -------------------------------------------------------------------------------- 1 | const fakeFetch = (paramter, delay, value) => { 2 | return new Promise((resolve, reject) => { 3 | setTimeout(() => { 4 | paramter ? resolve(value) : reject(`Promise rejected! ${value}`) 5 | }, delay) 6 | }) 7 | } 8 | 9 | function myPromiseAllSync(promises) { 10 | return new Promise((resolve, reject) => { 11 | let promiseResults = []; 12 | const results = promises.reduce((result, promise) => { 13 | return result.then(() => { 14 | return promise.then((value) => { 15 | promiseResults.push(value); 16 | return promiseResults; 17 | }); 18 | }).catch(err => reject(err)); 19 | }, Promise.resolve()); 20 | resolve(results); 21 | }) 22 | } 23 | 24 | myPromiseAllSync([fakeFetch(true, 1000, 'p1'), fakeFetch(true, 500, 'p2')]).then(results => console.log(results)); -------------------------------------------------------------------------------- /vanillaJs/toast-notification/src/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | } 4 | 5 | .toast__notifications { 6 | display: flex; 7 | flex-direction: column; 8 | position: absolute; 9 | bottom: 10px; 10 | right: 5px; 11 | } 12 | 13 | /* Separate normal notification from error notification */ 14 | .toast__notifications__error { 15 | display: flex; 16 | flex-direction: column; 17 | position: absolute; 18 | right: 5px; 19 | top: 10px; 20 | } 21 | 22 | /* common style for a toast notification*/ 23 | .toast { 24 | padding: 0.5rem; 25 | margin-bottom: 5px; 26 | border-radius: 10px; 27 | } 28 | 29 | .toast__info { 30 | background-color: cyan; 31 | } 32 | 33 | .toast__warning { 34 | background-color: yellow; 35 | } 36 | 37 | .toast__error { 38 | background-color: red; 39 | } 40 | -------------------------------------------------------------------------------- /promises/myFunctionWrapper.js: -------------------------------------------------------------------------------- 1 | const fakeFetch = (paramter, delay, value) => { 2 | return new Promise((resolve, reject) => { 3 | setTimeout(() => { 4 | paramter ? resolve(value) : reject(`Promise rejected! ${value}`) 5 | }, delay) 6 | }) 7 | } 8 | 9 | function functionWrapper(...functions) { 10 | return new Promise((resolve, reject) => { 11 | let promiseResults = []; 12 | const results = functions.reduce((result, fn) => { 13 | return result.then(() => { 14 | return fn().then((value) => { 15 | promiseResults.push(value) 16 | return promiseResults; 17 | }); 18 | }).catch(err => reject(err)); 19 | }, Promise.resolve()); 20 | resolve(results); 21 | }) 22 | } 23 | 24 | const fakeFetch1 = () => fakeFetch(true, 300, 'p1'); 25 | const fakeFetch2 = () => fakeFetch(true, 100, 'p2'); 26 | 27 | functionWrapper(fakeFetch1, fakeFetch2).then(res => console.log(res)); -------------------------------------------------------------------------------- /lodash-utilities/cloneDeep.js: -------------------------------------------------------------------------------- 1 | function cloneDeep(originalObj) { 2 | if (typeof originalObj !== "object") { 3 | return originalObj; 4 | } 5 | if (Array.isArray(originalObj)) { 6 | return originalObj.map((item) => cloneDeep(item)); 7 | } 8 | let copy = {}; 9 | for (let [key, value] of Object.entries(originalObj)) { 10 | copy = { ...copy, [key]: cloneDeep(value) } 11 | } 12 | return copy; 13 | } 14 | 15 | const movie = { 16 | name: 'F&F9', 17 | cast: [ 18 | { 19 | id: 1, 20 | name: 'Vin Diesel' 21 | } 22 | ], 23 | ratings: { 24 | count: 4.5, 25 | reactors: [ 26 | { 27 | userId: '12309', 28 | name: 'Taran' 29 | } 30 | ] 31 | } 32 | } 33 | 34 | const deepCopyOfMovie = cloneDeep(movie); 35 | 36 | console.log(deepCopyOfMovie === movie); 37 | 38 | deepCopyOfMovie.ratings.count = 4.3; 39 | 40 | console.log(JSON.stringify(movie)); 41 | 42 | console.log(JSON.stringify(deepCopyOfMovie)); -------------------------------------------------------------------------------- /DSA/array2DSpiral.js: -------------------------------------------------------------------------------- 1 | const array = [[1, 2, 3, 4], [5, 6, 7, 8], 2 | [9, 10, 11, 12], [13, 14, 15, 16]]; 3 | 4 | function printArraySpirally(arr) { 5 | let top = 0, left = 0; 6 | let right = arr[0].length; 7 | let bottom = arr.length; 8 | const result = []; 9 | 10 | while (top < bottom && left < right) { 11 | for (let i = left; i < right; i++) { 12 | result.push(arr[top][i]); 13 | } 14 | top += 1 15 | 16 | for (let i = top; i < bottom; i++) { 17 | result.push(arr[i][right - 1]); 18 | } 19 | right -= 1; 20 | 21 | if (top < bottom) { 22 | for (let i = right - 1; i >= left; i--) { 23 | result.push(arr[bottom - 1][i]); 24 | } 25 | bottom -= 1; 26 | } 27 | 28 | if (left < right) { 29 | for (let i = bottom - 1; i >= top; i--) { 30 | result.push(arr[i][left]); 31 | } 32 | left += 1; 33 | } 34 | } 35 | return result; 36 | } 37 | 38 | console.log(printArraySpirally(array)); -------------------------------------------------------------------------------- /promises/myPromiseAny.js: -------------------------------------------------------------------------------- 1 | const fakeFetch = (paramter, delay, value) => { 2 | return new Promise((resolve, reject) => { 3 | setTimeout(() => { 4 | paramter ? resolve(value) : reject(`Promise rejected! ${value}`) 5 | }, delay) 6 | }) 7 | } 8 | 9 | function myPromiseAny(promises) { 10 | let promiseResults = []; 11 | let rejectedPromiseCount = 0; 12 | return new Promise((resolve, reject) => { 13 | promises.forEach(async (promise) => { 14 | try { 15 | const output = await promise; 16 | resolve(output); 17 | } catch (err) { 18 | promiseResults.push(err); 19 | console.log(err); 20 | rejectedPromiseCount++; 21 | if (rejectedPromiseCount === promises.length) { 22 | reject(promiseResults); 23 | } 24 | } 25 | }) 26 | }) 27 | } 28 | 29 | myPromiseAny([fakeFetch(false, 1000, 'p1'), fakeFetch(false, 500, 'p2')]).then(results => console.log(results)).catch(err => console.log(err)); -------------------------------------------------------------------------------- /patterns/pubSub.js: -------------------------------------------------------------------------------- 1 | function pubSub() { 2 | // publisher method 3 | // subscriber method 4 | // subscribers object to store array of subsribers of each event method 5 | const subscribers = {}; 6 | 7 | function publish(eventName, data) { 8 | // no subscribers 9 | if (!Array.isArray(subscribers[eventName])) { 10 | return; 11 | } 12 | 13 | // call a function for each subscriber of event 14 | subscribers[eventName].forEach((callback) => callback(data)); 15 | } 16 | 17 | function subscribe(eventName, callback) { 18 | if (!Array.isArray(subscribers[eventName])) { 19 | subscribers[eventName] = []; 20 | } 21 | 22 | subscribers[eventName].push(callback); 23 | const indexOfSubscriber = subscribers[eventName].length - 1; 24 | 25 | return { 26 | unsubscribe() { 27 | return subscribers[eventName].splice(indexOfSubscriber, 1); 28 | } 29 | } 30 | } 31 | 32 | return { 33 | publish, 34 | subscribe 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /string-utilities/stringReplace.js: -------------------------------------------------------------------------------- 1 | function checkSubString(string, index, pattern) { 2 | for (let i = index, count = 0; i < string.length && count < pattern.length; i++ , count++) { 3 | if (string[i] !== pattern[count]) { 4 | return false; 5 | } 6 | } 7 | return true; 8 | } 9 | 10 | function getSubstring(string, start, end) { 11 | let resultString = ""; 12 | for(let i = start; i < end && i < string.length ; i++){ 13 | resultString+= string[i]; 14 | } 15 | return resultString; 16 | }; 17 | 18 | function myStringReplace(originalString, pattern, replaceString, replaceAll) { 19 | let resultString = originalString; 20 | for (let i = 0; i < originalString.length; i++) { 21 | if (checkSubString(resultString, i, pattern)) { 22 | resultString = getSubstring(resultString, 0, i) + replaceString + getSubstring(resultString, i + pattern.length, resultString.length); 23 | // console.log(resultString); 24 | } 25 | } 26 | return resultString; 27 | } 28 | 29 | console.log(myStringReplace('Javascript is awesome!', 'awesome', 'amazing', true)); -------------------------------------------------------------------------------- /recursion/zigZagSpiralTraversal.js: -------------------------------------------------------------------------------- 1 | const { BinarySearchTree } = require("./binarySearchTree"); 2 | 3 | const tree = new BinarySearchTree(); 4 | let root; 5 | root = tree.insertNode(root, 5); 6 | root = tree.insertNode(root, 1); 7 | root = tree.insertNode(root, 3); 8 | root = tree.insertNode(root, 2); 9 | root = tree.insertNode(root, 7); 10 | root = tree.insertNode(root, 9); 11 | root = tree.insertNode(root, 6); 12 | root = tree.insertNode(root, 10); 13 | 14 | function levelOrder(root) { 15 | const spiralLevels = []; 16 | function spiral(root, level) { 17 | if (!root) { 18 | return; 19 | } 20 | if (spiralLevels[level]) { 21 | level & 1 ? spiralLevels[level].unshift(root.val) : 22 | spiralLevels[level].push(root.val); 23 | } 24 | else { 25 | spiralLevels[level] = [root.val]; 26 | } 27 | 28 | spiral(root.left, level + 1); 29 | spiral(root.right, level + 1); 30 | } 31 | spiral(root, 0); 32 | return spiralLevels; 33 | } 34 | 35 | BinarySearchTree.prototype.levelOrder = levelOrder; 36 | 37 | console.log(tree.levelOrder(root)); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Jaynil Gaglani 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vanillaJs/toast-notification/src/index.js: -------------------------------------------------------------------------------- 1 | import "./styles.css"; 2 | 3 | function addToast(data) { 4 | const toastDiv = document.createElement("div"); 5 | toastDiv.classList.add(`toast__${data.type}`); 6 | toastDiv.classList.add("toast"); 7 | toastDiv.innerHTML = data.content; 8 | if (data.position === "true") { 9 | const toastDivError = document.querySelector(".toast__notifications__error"); 10 | toastDivError.appendChild(toastDiv); 11 | toastDiv.classList.add(`toast__top`); 12 | setTimeout(() => { 13 | toastDivError.removeChild(toastDiv); 14 | }, 2000); 15 | } else { 16 | const mainToastDiv = document.querySelector(".toast__notifications"); 17 | mainToastDiv.appendChild(toastDiv); 18 | setTimeout(() => { 19 | mainToastDiv.removeChild(toastDiv); 20 | }, 2000); 21 | } 22 | } 23 | 24 | function fun(e) { 25 | const type = e.target.getAttribute("type"); 26 | const content = e.target.getAttribute("content"); 27 | const position = e.target.getAttribute("top"); 28 | addToast({ type, content, position }); 29 | } 30 | 31 | document.querySelector(".buttons").addEventListener("click", fun); 32 | -------------------------------------------------------------------------------- /react-custom-hooks/useDebounce.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import "./styles.css"; 3 | 4 | const useDebounce = (searchValue, delay) => { 5 | const [state, setValue] = useState({ timer: null }); 6 | 7 | useEffect(() => { 8 | clearTimeout(state.timer); 9 | const timer = setTimeout( 10 | () => setValue((state) => ({ ...state, searchValue })), 11 | delay 12 | ); 13 | setValue((state) => ({ ...state, timer })); 14 | }, [searchValue, delay]); 15 | 16 | return state.searchValue; 17 | }; 18 | 19 | const Debounce = () => { 20 | const [text, setText] = useState(""); 21 | const delayedSearch = useDebounce(text, 1000); 22 | 23 | const handleChange = (e) => { 24 | e.preventDefault(); 25 | setText(e.target.value); 26 | }; 27 | 28 | return ( 29 |
30 | 36 |
Search Results
37 |
{delayedSearch}
38 |
39 | ); 40 | }; 41 | 42 | export default function App() { 43 | return ; 44 | } 45 | -------------------------------------------------------------------------------- /DSA/LRUCache.js: -------------------------------------------------------------------------------- 1 | class LRUCache { 2 | constructor(capacity) { 3 | this.cache = new Map(); 4 | this.capacity = capacity; 5 | } 6 | 7 | get(key) { 8 | const value = this.cache.get(key); 9 | if (value) { 10 | this.cache.delete(key); 11 | this.cache.set(key, value); 12 | } 13 | return value; 14 | } 15 | 16 | put(key, value) { 17 | this.cache.delete(key); 18 | if (this.cache.size === this.capacity) { 19 | this.cache.delete(this.cache.keys().next().value); 20 | } 21 | this.cache.set(key, value); 22 | } 23 | 24 | getRecentlyUsed() { 25 | return Array.from(this.cache)[this.cache.size - 1]; 26 | } 27 | 28 | getLeastUsed() { 29 | return this.cache.entries().next().value; 30 | } 31 | 32 | getAllEntries() { 33 | return Array.from(this.cache.entries()); 34 | } 35 | 36 | } 37 | 38 | const lru = new LRUCache(4); 39 | 40 | lru.put('store', 9); 41 | lru.put('store', 8); 42 | lru.put('red', 109); 43 | lru.put('green', 107); 44 | lru.put('blue', 108); 45 | console.log(lru.get('red')); 46 | lru.put('orange', 106); 47 | console.log(lru.get('store')); 48 | console.log(lru.getAllEntries()); 49 | console.log(lru.getRecentlyUsed()); 50 | console.log(lru.getLeastUsed()); -------------------------------------------------------------------------------- /react-snippets/event-delegation/src/App.js: -------------------------------------------------------------------------------- 1 | import "./styles.css"; 2 | 3 | export default function App() { 4 | const data = [ 5 | { character: "Neo", movie: "Matrix", imdbRating: "9" }, 6 | { character: "John Wick", movie: "John Wick", imdbRating: "8.5" }, 7 | { character: "John Constantine", movie: "Constantine", imdbRating: "8" } 8 | ]; 9 | 10 | function handleClick(e, item) { 11 | console.log(e.target.getAttribute("rating")); 12 | if (e.target.getAttribute("rating")) { 13 | alert(item.imdbRating); 14 | } else { 15 | const tempItem = item; 16 | alert(JSON.stringify(tempItem)); 17 | } 18 | } 19 | 20 | return ( 21 |
22 | 23 | 24 | {data.map((item, i) => ( 25 | handleClick(e, item)}> 26 | 27 | 28 | 33 | 34 | ))} 35 | 36 |
{item.character}{item.movie} 29 |
30 | Imdb Rating 31 |
32 |
37 |
38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /lodash-utilities/cloneDeepWithCircularDependency.js: -------------------------------------------------------------------------------- 1 | /** 2 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap 3 | * Using WeakMap here since keys of weakmap should be objects & 4 | * the keys are garbage collected easily when not referenced outside of weakmap 5 | * 6 | */ 7 | 8 | function isFunction(value) { 9 | return typeof value === "function"; 10 | } 11 | 12 | function isPrimitive(value) { 13 | return value !== Object(value); 14 | } 15 | 16 | function isObject(value) { 17 | return typeof value === "object"; 18 | } 19 | 20 | function cloneDeepWithCircularDependency(value, cache = new WeakMap()) { 21 | if (cache.has(value)) { 22 | return cache.get(value); 23 | } 24 | if (isPrimitive(value) || isFunction(value)) { 25 | return value; 26 | } 27 | if (Array.isArray(value)) { 28 | return value.map((element) => 29 | cloneDeepWithCircularDependency(element, cache) 30 | ); 31 | } 32 | const result = {}; 33 | cache.set(value, result); 34 | Object.entries(value).forEach(([key, value]) => { 35 | result[key] = cloneDeepWithCircularDependency(value, cache); 36 | }); 37 | return result; 38 | } 39 | 40 | function A() {} 41 | function B() {} 42 | let a = new A(); 43 | let b = new B(); 44 | a.b = b; 45 | b.a = a; 46 | 47 | const c = cloneDeepWithCircularDependency(a); 48 | console.log("a" in c.b.a.b); 49 | console.log(c) 50 | -------------------------------------------------------------------------------- /recursion/flattenArray.js: -------------------------------------------------------------------------------- 1 | const array = [1, [2, [3, 4], 5], 6]; 2 | 3 | function flattenArray(arr) { 4 | if (!arr.length) { 5 | return arr; 6 | } 7 | function recurseFlatten(arr, index, flattenedArray) { 8 | if (index === arr.length) { 9 | return flattenedArray; 10 | } 11 | if (!Array.isArray(arr[index])) { 12 | flattenedArray.push(arr[index]); 13 | } 14 | else { 15 | flattenedArray = flattenedArray.concat(recurseFlatten(arr[index], 0, [])); 16 | } 17 | return recurseFlatten(arr, index + 1, flattenedArray); 18 | } 19 | return recurseFlatten(arr, 0, []); 20 | }; 21 | 22 | console.log(flattenArray(array)); 23 | 24 | 25 | function flattenArrayDepth(arr, depth = 1) { 26 | if (!arr.length) { 27 | return arr; 28 | } 29 | function recurseFlatten(arr, index, flattenedArray, depth) { 30 | if (index === arr.length) { 31 | return flattenedArray; 32 | } 33 | if (depth < 0) { 34 | flattenedArray.push(arr) 35 | return flattenedArray; 36 | } 37 | if (!Array.isArray(arr[index])) { 38 | flattenedArray.push(arr[index]); 39 | } 40 | else { 41 | flattenedArray = flattenedArray.concat(recurseFlatten(arr[index], 0, [], depth - 1)); 42 | } 43 | return recurseFlatten(arr, index + 1, flattenedArray, depth); 44 | } 45 | return recurseFlatten(arr, 0, [], depth); 46 | }; 47 | 48 | console.log(flattenArrayDepth(array, 1)); -------------------------------------------------------------------------------- /js-coding-questions/readCSVFile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * https://www.naukri.com/code360/library/how-to-read-csv-file-in-javascript 3 | * 4 | * readInterface.on("line", ...): It is called for each line in the CSV file. It splits each line using a comma as the delimiter and adds it as an array to the output array. 5 | * readInterface.on("close", ...): It is called when the end of the file is reached. The entire file data is now read in the output. 6 | * readInterface.on("error", ...): It handles the errors and logs an error message. 7 | */ 8 | 9 | /** 10 | * When we use the readFile() to read the CSV file, it also takes much memory because it reads the whole csv file at once 11 | * The stream helps the user to access a large amount of data by creating simpler chunks of larger data. 12 | */ 13 | 14 | const fs = require("fs"); 15 | const readLine = require("readline"); 16 | 17 | // Create a read stream 18 | const stream = fs.createReadStream("./sampleCSV.csv"); 19 | 20 | // Create a readline interface 21 | const readInterface = readLine.createInterface({ input: stream }); 22 | 23 | const output = []; 24 | 25 | // Event handler for reading lines 26 | readInterface.on("line", (row) => { 27 | output.push(row.split(",")); 28 | }); 29 | 30 | // Event handler for the end of file 31 | readInterface.on("close", () => { 32 | console.log(output); 33 | }); 34 | 35 | // Event handler for handling errors 36 | readInterface.on("error", (err) => { 37 | console.error("Error reading the CSV file:", err); 38 | }); 39 | -------------------------------------------------------------------------------- /recursion/arrayToList.js: -------------------------------------------------------------------------------- 1 | // Question taken from (https://eloquentjavascript.net/04_data.html#i_nSTX34CM1M) 2 | 3 | // ------------------- Array To List ---------------------- 4 | 5 | function arrayToList(arr) { 6 | function constructList(arr, index) { 7 | if (index === arr.length - 1) { 8 | return { 9 | value: arr[index], 10 | rest: null 11 | } 12 | } 13 | return { 14 | value: arr[index], 15 | rest: constructList(arr, index + 1) 16 | } 17 | } 18 | return constructList(arr, 0); 19 | } 20 | 21 | const array = [1, 2, 3]; 22 | 23 | const list = arrayToList(array); 24 | 25 | console.log(list); 26 | 27 | // ------------------- List To Array ---------------------- 28 | 29 | function listToArray(list) { 30 | if (!list) { 31 | return []; 32 | } 33 | 34 | function constructArray(list, arr) { 35 | if (list.rest === null) { 36 | arr.push(list.value); 37 | return arr; 38 | } 39 | arr.push(list.value) 40 | return constructArray(list.rest, arr); 41 | } 42 | return constructArray(list, []); 43 | } 44 | 45 | const arrayFromList = listToArray(list); 46 | 47 | console.log(arrayFromList); 48 | 49 | // ------------------- Prepend To List --------------------- 50 | 51 | function prependToList(element, list) { 52 | if (!list) { 53 | return []; 54 | } 55 | 56 | return { 57 | value: element, 58 | rest: list 59 | } 60 | } 61 | 62 | const newList = prependToList(0, list); 63 | 64 | console.log(newList); -------------------------------------------------------------------------------- /promises/myPromiseAll.js: -------------------------------------------------------------------------------- 1 | const fakeFetch = (paramter, delay, value) => { 2 | return new Promise((resolve, reject) => { 3 | setTimeout(() => { 4 | paramter ? resolve(value) : reject(`Promise rejected! ${value}`) 5 | }, delay) 6 | }) 7 | } 8 | 9 | // function myPromiseAll(promises) { 10 | // let promiseResults = []; 11 | // let completedPromiseCount = 0; 12 | // return new Promise((resolve, reject) => { 13 | // promises.forEach(async (promise) => { 14 | // try { 15 | // const output = await promise; 16 | // promiseResults.push(output); 17 | // completedPromiseCount++; 18 | // if (completedPromiseCount === promises.length) { 19 | // resolve(promiseResults); 20 | // } 21 | // } catch (err) { 22 | // reject(err); 23 | // } 24 | // }) 25 | // }) 26 | // } 27 | 28 | function myPromiseAll(promises) { 29 | return new Promise((resolve, reject) => { 30 | let promiseResults = Array(promises.length); 31 | let completedPromiseCount = 0; 32 | promises.forEach(async (promise, index) => { 33 | try { 34 | promiseResults[index] = await promise; 35 | completedPromiseCount++; 36 | if (completedPromiseCount === promises.length) { 37 | resolve(promiseResults); 38 | } 39 | } catch (err) { 40 | reject(err); 41 | } 42 | }) 43 | }) 44 | } 45 | 46 | myPromiseAll([fakeFetch(true, 1000, 'p1'), fakeFetch(true, 500, 'p2')]).then(results => console.log(results)); -------------------------------------------------------------------------------- /DSA/maxStack.js: -------------------------------------------------------------------------------- 1 | const MinStack = function() { 2 | this.stack = new Array(); 3 | this.stackTop = -1; 4 | }; 5 | 6 | /** 7 | * @param {number} val 8 | * @return {void} 9 | */ 10 | MinStack.prototype.push = function(val) { 11 | if(!this.isEmpty()){ 12 | min = this.stack[this.stackTop][1]; 13 | min = val < min ? val : min; 14 | this.stackTop++; 15 | return this.stack.push([val, min]); 16 | } 17 | this.stackTop++; 18 | this.stack.push([val, val]) 19 | }; 20 | 21 | /** 22 | * @return {void} 23 | */ 24 | MinStack.prototype.pop = function() { 25 | if(!this.isEmpty()){ 26 | this.stackTop--; 27 | return this.stack.pop()[0]; 28 | } 29 | }; 30 | 31 | /** 32 | * @return {number} 33 | */ 34 | MinStack.prototype.top = function() { 35 | if(!this.isEmpty()){ 36 | return this.stack[this.stackTop][0]; 37 | } 38 | }; 39 | 40 | /** 41 | * @return {number} 42 | */ 43 | MinStack.prototype.getMin = function() { 44 | if(!this.isEmpty()){ 45 | return this.stack[this.stackTop][1]; 46 | } 47 | }; 48 | 49 | /** 50 | * @return {boolean} 51 | */ 52 | MinStack.prototype.isEmpty = function(){ 53 | return this.stackTop === -1 ? true : false; 54 | } 55 | 56 | const minStack = new MinStack(); 57 | minStack.push(-2); 58 | minStack.push(0); 59 | minStack.push(-3); 60 | console.log(minStack.getMin()); // return -3 61 | console.log(minStack.pop()); 62 | console.log(minStack.top()); // return 0 63 | console.log(minStack.getMin()); // return -2 -------------------------------------------------------------------------------- /react-custom-hooks/useMemo.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import "./styles.css"; 3 | 4 | const useMyMemo = (func, dependencies) => { 5 | const [values, setValues] = useState([]); 6 | const [memoizedValue, setMemoizedValue] = useState(null); 7 | 8 | const hasChanged = (dependencies) => { 9 | return values.length === 0 10 | ? true 11 | : values.some((value, i) => value !== dependencies[i]); 12 | }; 13 | 14 | if (Array.isArray(dependencies) && hasChanged(dependencies)) { 15 | setValues(dependencies); 16 | setMemoizedValue(func.call(this)); 17 | console.log("called"); 18 | } 19 | return memoizedValue; 20 | }; 21 | 22 | const Memo = () => { 23 | const [number, setNumber] = useState(5); 24 | function summation(n) { 25 | return n < 1 ? n : n + summation(n - 1); 26 | } 27 | 28 | const handleSubmit = (e) => { 29 | e.preventDefault(); 30 | setNumber(Number(e.target.form[0].value)); 31 | }; 32 | 33 | const memoizedValue = useMyMemo(() => summation(number), [number]); 34 | 35 | console.log(memoizedValue); 36 | 37 | return ( 38 | <> 39 |
40 |

{memoizedValue}

41 |
42 | 47 | 50 |
51 |
52 | 53 | ); 54 | }; 55 | 56 | export default function App() { 57 | return ; 58 | } 59 | -------------------------------------------------------------------------------- /DSA/stackBalancedParanthesis.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor(size) { 3 | this.size = size; 4 | this.data = new Array(size); 5 | this.currentIndex = -1; 6 | } 7 | 8 | push(params) { 9 | let succeeded = false; 10 | if (this.currentIndex < this.size - 1) { 11 | this.currentIndex++; 12 | this.data[this.currentIndex] = params; 13 | succeeded = true; 14 | } 15 | return succeeded; 16 | } 17 | 18 | pop() { 19 | let poppedElement = null; 20 | if (!this.isEmpty()) { 21 | poppedElement = this.data[this.currentIndex]; 22 | this.data[this.currentIndex] = null; 23 | this.currentIndex--; 24 | } 25 | return poppedElement; 26 | } 27 | 28 | topOfStack() { 29 | let poppedElement = null; 30 | if (!this.isEmpty()) { 31 | poppedElement = this.data[this.currentIndex]; 32 | } 33 | return poppedElement; 34 | } 35 | 36 | isEmpty() { 37 | return this.currentIndex === -1 ? true : false; 38 | } 39 | } 40 | 41 | const matchBracket = { 42 | "[": "]", 43 | "{": "}", 44 | "(": ")" 45 | }; 46 | 47 | const checkBalancedParanthesis = (string) => { 48 | const stack = new Stack(string.length); 49 | for (let i = 0; i < string.length; i++) { 50 | if (Object.keys(matchBracket).includes(string[i])) { 51 | stack.push(string[i]); 52 | } else if ( 53 | !stack.isEmpty() && 54 | matchBracket[stack.topOfStack()] === string[i] 55 | ) { 56 | stack.pop(); 57 | } else { 58 | break; 59 | } 60 | } 61 | return stack.isEmpty() ? true : false; 62 | }; 63 | 64 | console.log(checkBalancedParanthesis("[({})]")); 65 | -------------------------------------------------------------------------------- /js-coding-questions/findObjectPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * https://srijansinghgulati.medium.com/find-path-in-a-js-object-my-favorite-question-to-ask-in-a-frontend-interview-faab189e2c19 3 | * 4 | * Problem Statement: 5 | - Write method findPath 6 | - Should take two params: 7 | - object 8 | - keys separated by dots as string 9 | - Return value if it exists at that path inside the object, else return undefined 10 | */ 11 | 12 | function findObjectPath(object, path) { 13 | let result = object; 14 | const pathArray = path.split("."); 15 | 16 | // checking if the key is object's own property or inherited property e.g. toString() 17 | pathArray.forEach((key) => { 18 | if (result && result.hasOwnProperty(key)) { 19 | result = result[key]; 20 | } else { 21 | result = undefined; 22 | } 23 | }); 24 | return result; 25 | } 26 | 27 | var obj = { 28 | a: { 29 | b: { 30 | c: 12, 31 | j: false, 32 | }, 33 | k: null, 34 | }, 35 | }; 36 | 37 | console.log(findObjectPath(obj, 'a.b.c')); // 12 38 | console.log(findObjectPath(obj, 'a.b')); // {c: 12, j: false} 39 | console.log(findObjectPath(obj, 'a.b.d')); // undefined 40 | console.log(findObjectPath(obj, 'a.c')); // undefined 41 | console.log(findObjectPath(obj, 'a.b.c.d')); // undefined 42 | console.log(findObjectPath(obj, 'a.b.c.d.e')); // undefined 43 | console.log(findObjectPath(obj, 'a.b.j')); //false 44 | console.log(findObjectPath(obj, 'a.b.j.k')); //undefined 45 | console.log(findObjectPath(obj, 'a.k')); //null 46 | console.log(findObjectPath(obj, 'a.k.j')); // undefined 47 | console.log(findObjectPath(obj, 'a.toString')); // undefined 48 | -------------------------------------------------------------------------------- /js-coding-questions/groupBy.js: -------------------------------------------------------------------------------- 1 | // Suppose you have input like: 2 | 3 | var skillsArray = [ 4 | { skill: 'css', user: 'Bill' }, 5 | { skill: 'javascript', user: 'Chad' }, 6 | { skill: 'javascript', user: 'Bill' }, 7 | { skill: 'css', user: 'Sue' }, 8 | { skill: 'javascript', user: 'Sue' }, 9 | { skill: 'html', user: 'Sue' } 10 | ]; 11 | 12 | // Convert it into result of the following form: 13 | // [ 14 | // { skill: 'javascript', user: [ 'Chad', 'Bill', 'Sue' ], count: 3 }, 15 | // { skill: 'css', user: [ 'Sue', 'Bill' ], count: 2 }, 16 | // { skill: 'html', user: [ 'Sue' ], count: 1 } 17 | // ] 18 | 19 | function groupBySkill(array) { 20 | return Object.values(array.reduce((result, { skill, user }) => { 21 | if (!result[skill]) { 22 | return { ...result, [skill]: { skill, user: [user], count: 1 } }; 23 | } 24 | const obj = result[skill]; 25 | return { ...result, [skill]: { skill, user: obj.user.concat(user), count: obj.count + 1 } } 26 | }, {})).sort((a, b) => a.count < b.count ? 1 : -1); 27 | } 28 | 29 | console.log(groupBySkill(skillsArray)); 30 | 31 | 32 | // function groupBySkill(array) { 33 | // return array.reduce((result, { skill, user }) => { 34 | 35 | // const skillExists = result.filter((res) => res.skill === skill).length; 36 | 37 | // if (!result.length || !skillExists) { 38 | // return result.concat({ skill, user: [user], count: 1 }) 39 | // } 40 | // return result.map((res) => { 41 | // return skill === res.skill ? { ...res, user: res.user.concat(user), count: res.count + 1 } : res; 42 | // }) 43 | // }, []).sort((a, b) => a.count < b.count ? 1 : -1) 44 | // } 45 | -------------------------------------------------------------------------------- /react-custom-hooks/useCallback.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import "./styles.css"; 3 | 4 | const useMyMemo = (func, dependencies) => { 5 | const [values, setValues] = useState([]); 6 | const [memoizedValue, setMemoizedValue] = useState(func); 7 | const hasChanged = (dependencies) => { 8 | return values.length === 0 9 | ? true 10 | : values.some((value, i) => value !== dependencies[i]); 11 | }; 12 | 13 | if (Array.isArray(dependencies) && hasChanged(dependencies)) { 14 | setMemoizedValue(() => func()); 15 | setValues(dependencies); 16 | console.log("called"); 17 | } 18 | return memoizedValue; 19 | }; 20 | 21 | const useMyCallback = (func, dependencies) => 22 | useMyMemo(() => func, dependencies); 23 | 24 | const Callback = () => { 25 | const [number, setNumber] = useState(5); 26 | function summation(n) { 27 | return n < 1 ? n : n + summation(n - 1); 28 | } 29 | 30 | const handleSubmit = (e) => { 31 | e.preventDefault(); 32 | setNumber(Number(e.target.form[0].value)); 33 | }; 34 | 35 | const memoizedFunc = useMyCallback(() => summation(number), [number]); 36 | 37 | return ( 38 | <> 39 |
40 |

{memoizedFunc()}

41 |
42 | 47 | 50 |
51 |
52 | 53 | ); 54 | }; 55 | 56 | export default function App() { 57 | return ; 58 | } 59 | -------------------------------------------------------------------------------- /currying/infiniteCurrying.js: -------------------------------------------------------------------------------- 1 | // function currying(fn) { 2 | // const N = fn.length; 3 | // function recCurr(n, args) { 4 | // return function innerFunc(...a){ 5 | // if (n <= a.length) { 6 | // return fn(...args, ...a); 7 | // } 8 | // return recCurr(n - a.length, [...args, ...a]) 9 | // } 10 | // } 11 | // return recCurr(N, []); 12 | // } 13 | 14 | // function currying(func){ 15 | // return function curried(...args){ 16 | // if(func.length <= args.length){ 17 | // return func.apply(this, args); 18 | // } 19 | // return function(...args2){ 20 | // return curried.apply(this, [...args, ...args2]) 21 | // } 22 | // } 23 | // }; 24 | 25 | function infiniteCurryingWithVariableArg(func) { 26 | function recursiveCurry(...args) { 27 | return function(...a) { 28 | if (!a.length) { 29 | return args.reduce((result, value) => { 30 | return func.call(func, result, value); 31 | }); 32 | } 33 | return recursiveCurry(...args, ...a); 34 | } 35 | } 36 | return recursiveCurry(); 37 | }; 38 | 39 | function infiniteCurrying(func) { 40 | function recursiveCurry(...args) { 41 | return function(a) { 42 | if (!a) { 43 | return args.reduce((result, value) => { 44 | return func.call(func, result, value); 45 | }); 46 | } 47 | return recursiveCurry(...args, a); 48 | } 49 | } 50 | return recursiveCurry(); 51 | }; 52 | 53 | // Arrow Functions 54 | const fn = infiniteCurrying((a, b) => a + b); 55 | const fn2 = infiniteCurryingWithVariableArg((a, b) => a + b); 56 | console.log(fn(7)(8)(9)()); 57 | console.log(fn2(7)(7, 8)(9, 7)()); -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | 21 | -------------------------------------------------------------------------------- /string-utilities/stringCasing.js: -------------------------------------------------------------------------------- 1 | // ---------------------------- capitalize ------------------------- 2 | 3 | function capitalize(string) { 4 | return string ? string.charAt(0).toUpperCase() + string.slice(1) : string; 5 | } 6 | 7 | console.log(capitalize('javascript is awesome!')); 8 | 9 | // ---------------------------- toUpperCase ------------------------- 10 | 11 | function toUpperCase(string) { 12 | let resultString = ""; 13 | for (let char of string) { 14 | const charCode = char.charCodeAt(); 15 | if (97 <= charCode && charCode <= 122) { 16 | resultString += String.fromCharCode(charCode - 32); 17 | } 18 | else { 19 | resultString += char; 20 | } 21 | } 22 | return resultString; 23 | } 24 | 25 | console.log(toUpperCase('javascript is awesome!')); 26 | 27 | // ---------------------------- toLowerCase ------------------------- 28 | 29 | function toLowerCase(string) { 30 | let resultString = ""; 31 | for (let char of string) { 32 | const charCode = char.charCodeAt(); 33 | if (65 <= charCode && charCode <= 90) { 34 | resultString += String.fromCharCode(charCode + 32) 35 | } else { 36 | resultString += char; 37 | } 38 | } 39 | return resultString; 40 | } 41 | 42 | console.log(toLowerCase("JAVASCRIPT IS AWESOME!")); 43 | 44 | // ---------------------------- toSnakeCase ------------------------- 45 | 46 | function toSnakeCase(string){ 47 | let resulString = ""; 48 | return toLowerCase(string).split(" ").join("_"); 49 | } 50 | 51 | console.log(toSnakeCase("JAVASCRIPT IS AWESOME!")); 52 | 53 | // ---------------------------- toStartCase ------------------------- 54 | 55 | function toStartCase(string){ 56 | let resultArray = string.split(" "); 57 | resultArray = resultArray.map(string => { 58 | return toUpperCase(string[0]) + string.slice(1); 59 | }) 60 | return resultArray.join(" "); 61 | } 62 | 63 | console.log(toStartCase("javascript is awesome!")); -------------------------------------------------------------------------------- /ObjectOrientedJS/objectsInDepth.js: -------------------------------------------------------------------------------- 1 | const bicycle = { 2 | color : 'red', 3 | 1: 'one' 4 | } 5 | 6 | bicycle.1; 7 | // Uncaught SyntaxError: Unexpected number 8 | 9 | bicycle[1]; 10 | // (returns the value of the `1` property) 11 | 12 | //------------------------------------------------------------ 13 | 14 | const myVariable = 'color'; 15 | 16 | bicycle[myVariable]; 17 | // 'blue' 18 | 19 | bicycle.myVariable; 20 | // undefined 21 | 22 | //------------------------------------------------------------ 23 | 24 | functionchangeToEight(n) { 25 | n = 8; // here local copy of n is created & n becomes 8 only in this function's scope 26 | } 27 | 28 | let n = 7; 29 | changeToEight(n); 30 | console.log(n); 31 | 32 | //------------------------------------------------------------ 33 | 34 | const originalObject = { 35 | favoriteColor: 'red' 36 | }; 37 | 38 | functionsetToBlue(object) { 39 | object.favoriteColor = 'blue'; 40 | } 41 | 42 | setToBlue(originalObject); 43 | originalObject.favoriteColor; 44 | // 'blue' 45 | 46 | // Also, the same thing happens in the case of object copy 47 | const duplicateObject = originalObject; 48 | duplicateObject.favoriteColor = 'orange'; 49 | 50 | duplicateObject.favoriteColor 51 | // 'orange' 52 | originalObject.favoriteColor; 53 | // 'orange' 54 | // originalObject property is also changed due to pass by reference 55 | 56 | //------------------------------------------------------------ 57 | 58 | const parrot = { 59 | group: 'bird', 60 | feathers: true, 61 | chirp:function () { 62 | console.log('Chirp chirp!'); 63 | } 64 | }; 65 | 66 | const pigeon = { 67 | group: 'bird', 68 | feathers: true, 69 | chirp:function () { 70 | console.log('Chirp chirp!'); 71 | } 72 | }; 73 | 74 | parrot === pigeon; // objects are not pointing to the same value in memory 75 | // false 76 | 77 | const myBird = parrot; 78 | 79 | myBird === parrot; // same object reference 80 | // true 81 | 82 | myBird === pigeon; 83 | // false 84 | 85 | // -------------------------------------------------------------------------------- /react-snippets/timer.js: -------------------------------------------------------------------------------- 1 | import { useRef, useState } from "react"; 2 | import "./styles.css"; 3 | 4 | const initialTimer = { minutes: 0, seconds: 0 }; 5 | 6 | const Timer = () => { 7 | const [timer, setTimer] = useState(initialTimer); 8 | const inputRef = useRef(null); 9 | 10 | const timeChangeHandler = (e) => { 11 | e.preventDefault(); 12 | setTimer((timer) => ({ ...timer, minutes: e.target.value })); 13 | }; 14 | 15 | const startTimer = (e) => { 16 | e.preventDefault(); 17 | const id = setInterval(() => { 18 | setTimer(({ minutes, seconds }) => { 19 | if (minutes === 0 && seconds === 0) { 20 | clearInterval(id); 21 | return initialTimer; 22 | } 23 | return seconds === 0 24 | ? { minutes: minutes - 1, seconds: 59 } 25 | : { minutes, seconds: seconds - 1 }; 26 | }); 27 | }, 1000); 28 | inputRef.current = { interval: id }; 29 | }; 30 | 31 | const stopTimer = (e) => { 32 | e.preventDefault(); 33 | clearInterval(inputRef.current?.interval); 34 | }; 35 | 36 | const resetTimer = (e) => { 37 | e.preventDefault(); 38 | setTimer(initialTimer); 39 | clearInterval(inputRef.current?.interval); 40 | }; 41 | 42 | const clearInput = (e) => { 43 | e.target.value = ""; 44 | }; 45 | 46 | const { minutes, seconds } = timer; 47 | 48 | const getColor = () => { 49 | return minutes === 0 && seconds <= 5 ? "red" : "initial"; 50 | }; 51 | 52 | return ( 53 | <> 54 |
55 | 56 | 63 | 66 | 67 | 70 |
71 |
{`${minutes} : ${seconds}`}
72 | 73 | ); 74 | }; 75 | 76 | export default function App() { 77 | return ( 78 |
79 | 80 |
81 | ); 82 | } 83 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '26 8 * * 6' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v2 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v1 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v1 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v1 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

JavaScript Interview Questions

3 |

Curated interview questions with solutions on JavaScript specially for

4 |

Interviewers | Interviewees | Practice

5 | banner 6 |
7 | 8 |
9 |

10 | 11 | 12 | 13 | 14 | 15 | 16 |

17 |
18 | 19 | ### Contributing Guide 20 | 21 | If you want to contribute, improve or suggest changes to this repo, then check out the [Contributing Guide](./CONTRIBUTING.md) 22 |

23 | 24 | ### Stargazers 25 | 26 | [![Stargazers repo roster for @Jaynil1611/Javascript-Interview-Preparation](https://reporoster.com/stars/Jaynil1611/Javascript-Interview-Preparation)](https://github.com/Jaynil1611/Javascript-Interview-Preparation/stargazers) 27 | 28 | ### Forkers 29 | 30 | [![Forkers repo roster for @Jaynil1611/Javascript-Interview-Preparation](https://reporoster.com/forks/Jaynil1611/Javascript-Interview-Preparation)](https://github.com/Jaynil1611/Javascript-Interview-Preparation/network/members) 31 | 32 | 33 | ### 👤 **Jaynil Gaglani** 34 | 35 | - Portfolio: [jaynil.gaglani](https://bit.ly/jaynil-profile) 36 | - Linkedin: [Jaynil Gaglani](https://www.linkedin.com/in/jaynilgaglani/) 37 | - Github: [@Jaynil1611](https://github.com/Jaynil1611) 38 | 39 | ### Show your support 40 | Give a ⭐️ if you like this repository! 41 | 42 | Made with ❤️ by Jaynil Gaglani 43 | 44 | ### License 45 | 46 | This repository is MIT licensed. [Read more](./LICENSE) -------------------------------------------------------------------------------- /recursion/binarySearchTree.js: -------------------------------------------------------------------------------- 1 | function Node(val = null) { 2 | this.val = val; 3 | this.left = null; 4 | this.right = null; 5 | } 6 | 7 | function BinarySearchTree() { 8 | this.insertNode = function insert(root, insertVal) { 9 | if (!root) { 10 | return new Node(insertVal); 11 | } 12 | if (root.val === insertVal) { 13 | return root; 14 | } 15 | if (root.val > insertVal) { 16 | root.left = insert(root.left, insertVal) 17 | } else { 18 | root.right = insert(root.right, insertVal) 19 | } 20 | return root; 21 | } 22 | 23 | this.searchNode = function search(root, searchVal) { 24 | if (!root) { 25 | return `Node with value ${searchVal} not found`; 26 | } 27 | if (root.val === searchVal) { 28 | return root; 29 | } 30 | if (root.val > searchVal) { 31 | return search(root.left, searchVal); 32 | } 33 | return search(root.right, searchVal); 34 | } 35 | 36 | this.preorderTraversal = function preorder(root) { 37 | if (root) { 38 | console.log(root.val); 39 | preorder(root.left); 40 | preorder(root.right); 41 | } 42 | } 43 | 44 | this.inorderTraversal = function inorder(root) { 45 | if (root) { 46 | inorder(root.left); 47 | console.log(root.val); 48 | inorder(root.right); 49 | } 50 | } 51 | 52 | this.postorderTraversal = function postorder(root) { 53 | if (root) { 54 | postorder(root.left); 55 | postorder(root.right); 56 | console.log(root.val); 57 | } 58 | } 59 | 60 | function getInorderSuccessor(root) { 61 | let current = root; 62 | while (current.left) { 63 | current = current.left; 64 | } 65 | return current; 66 | } 67 | 68 | this.deleteNode = function remove(root, deleteVal) { 69 | if (!root) { 70 | return root; 71 | } 72 | if (root.val < deleteVal) { 73 | root.left = remove(root.left, deleteVal); 74 | } 75 | else if (root.val > deleteVal) { 76 | root.right = remove(root.right, deleteVal); 77 | } 78 | else { 79 | let temp = null; 80 | if (!root.left) { 81 | temp = root.right; 82 | root = null; 83 | return temp; 84 | } 85 | else if (!root.right) { 86 | temp = root.left; 87 | root = null; 88 | return temp; 89 | } 90 | temp = getInorderSuccessor(root.right); 91 | root.val = temp.val; 92 | root.right = remove(root.right, temp.val); 93 | } 94 | return root; 95 | } 96 | } 97 | 98 | const tree = new BinarySearchTree(); 99 | let root = null; 100 | root = tree.insertNode(root, 5); 101 | root = tree.insertNode(root, 2); 102 | root = tree.insertNode(root, 9); 103 | tree.inorderTraversal(root); 104 | console.log(tree.searchNode(root, 2)); 105 | tree.preorderTraversal(root); 106 | root = tree.deleteNode(root, 5); 107 | console.log(root); 108 | 109 | module.exports = { BinarySearchTree }; -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | In the interest of fostering an open and welcoming environment, we as 7 | contributors and maintainers pledge to make participation in our project and 8 | our community a harassment-free experience for everyone, regardless of age, body 9 | size, disability, ethnicity, sex characteristics, gender identity and expression, 10 | level of experience, education, socio-economic status, nationality, personal 11 | appearance, race, religion, or sexual identity and orientation. 12 | 13 | ## Our Standards 14 | 15 | Examples of behavior that contributes to creating a positive environment 16 | include: 17 | 18 | * Using welcoming and inclusive language 19 | * Being respectful of differing viewpoints and experiences 20 | * Gracefully accepting constructive criticism 21 | * Focusing on what is best for the community 22 | * Showing empathy towards other community members 23 | 24 | Examples of unacceptable behavior by participants include: 25 | 26 | * The use of sexualized language or imagery and unwelcome sexual attention or 27 | advances 28 | * Trolling, insulting/derogatory comments, and personal or political attacks 29 | * Public or private harassment 30 | * Publishing others' private information, such as a physical or electronic 31 | address, without explicit permission 32 | * Other conduct which could reasonably be considered inappropriate in a 33 | professional setting 34 | 35 | ## Our Responsibilities 36 | 37 | Project maintainers are responsible for clarifying the standards of acceptable 38 | behavior and are expected to take appropriate and fair corrective action in 39 | response to any instances of unacceptable behavior. 40 | 41 | Project maintainers have the right and responsibility to remove, edit, or 42 | reject comments, commits, code, wiki edits, issues, and other contributions 43 | that are not aligned to this Code of Conduct, or to ban temporarily or 44 | permanently any contributor for other behaviors that they deem inappropriate, 45 | threatening, offensive, or harmful. 46 | 47 | ## Scope 48 | 49 | This Code of Conduct applies within all project spaces, and it also applies when 50 | an individual is representing the project or its community in public spaces. 51 | Examples of representing a project or community include using an official 52 | project e-mail address, posting via an official social media account, or acting 53 | as an appointed representative at an online or offline event. Representation of 54 | a project may be further defined and clarified by project maintainers. 55 | 56 | ## Enforcement 57 | 58 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 59 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All 60 | complaints will be reviewed and investigated and will result in a response that 61 | is deemed necessary and appropriate to the circumstances. The project team is 62 | obligated to maintain confidentiality with regard to the reporter of an incident. 63 | Further details of specific enforcement policies may be posted separately. 64 | 65 | Project maintainers who do not follow or enforce the Code of Conduct in good 66 | faith may face temporary or permanent repercussions as determined by other 67 | members of the project's leadership. 68 | 69 | ## Attribution 70 | 71 | This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, 72 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 73 | 74 | For answers to common questions about this code of conduct, see 75 | https://www.contributor-covenant.org/faq 76 | -------------------------------------------------------------------------------- /polyfills/myPromise.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | 5 | class MyPromise { 6 | constructor(executor) { 7 | this.state = "pending"; 8 | this.value = undefined; 9 | this.error = undefined; 10 | this.onFulfilledCallbacks = []; 11 | this.onRejectedCallbacks = []; 12 | 13 | const resolve = (val) => { 14 | if (this.state === "pending") { 15 | this.state = "fulfilled"; 16 | this.value = val; 17 | this.onFulfilledCallbacks.forEach((callback) => callback(this.value)); 18 | } 19 | }; 20 | const reject = (err) => { 21 | if (this.state === "pending") { 22 | this.state = "rejected"; 23 | this.error = err; 24 | this.onRejectedCallbacks.forEach((callback) => callback(this.error)); 25 | } 26 | }; 27 | try { 28 | executor(resolve, reject); 29 | } catch (error) { 30 | reject(error); 31 | } 32 | } 33 | 34 | then(onResolve, onReject) { 35 | onResolve = typeof onResolve === "function" ? onResolve : (value) => value; 36 | onReject = 37 | typeof onReject === "function" 38 | ? onReject 39 | : (reason) => { 40 | throw reason; 41 | }; 42 | 43 | return new MyPromise((resolve, reject) => { 44 | if (this.state === "fulfilled") { 45 | queueMicrotask(() => { 46 | try { 47 | const result = onResolve(this.value); 48 | resolve(result); 49 | } catch (err) { 50 | reject(err); 51 | } 52 | }); 53 | } 54 | 55 | if (this.state === "rejected") { 56 | queueMicrotask(() => { 57 | try { 58 | const result = onReject(this.error); 59 | resolve(result); 60 | } catch (err) { 61 | reject(err); 62 | } 63 | }); 64 | } 65 | 66 | if (this.state === "pending") { 67 | this.onFulfilledCallbacks.push(() => { 68 | queueMicrotask(() => { 69 | try { 70 | const result = onResolve(this.value); 71 | resolve(result); 72 | } catch (err) { 73 | reject(err); 74 | } 75 | }); 76 | }); 77 | 78 | this.onRejectedCallbacks.push(() => { 79 | queueMicrotask(() => { 80 | try { 81 | const result = onReject(this.error); 82 | resolve(result); 83 | } catch (err) { 84 | reject(err); 85 | } 86 | }); 87 | }); 88 | } 89 | }); 90 | } 91 | 92 | catch(onRejected) { 93 | return this.then(null, onRejected); 94 | } 95 | 96 | finally(onFinally) { 97 | return this.then( 98 | (value) => { 99 | onFinally(); 100 | return value; 101 | }, 102 | (err) => { 103 | onFinally(); 104 | throw err; 105 | } 106 | ); 107 | } 108 | 109 | static resolve(val) { 110 | return new MyPromise((resolve) => resolve(val)); 111 | } 112 | 113 | static reject(err) { 114 | return new MyPromise((_, reject) => reject(err)); 115 | } 116 | } 117 | 118 | const promise = new MyPromise((resolve, reject) => { 119 | setTimeout(() => resolve("Resolved!"), 1000); 120 | }); 121 | 122 | // console.log(promise); 123 | promise 124 | .then((value) => { 125 | console.log(value); 126 | // "Resolved!" 127 | return "Chained Value"; 128 | }) 129 | .catch((error) => { 130 | console.error(error); 131 | }) 132 | .then((value) => { 133 | console.log(value); 134 | // "Chained Value" 135 | }) 136 | .finally(() => { 137 | console.log("Promise settled."); 138 | }); 139 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to [Javascript-Interview-Preparation](https://github.com/Jaynil1611/Javascript-Interview-Preparation) 2 | 3 | 4 | ## Before getting started 5 | 6 | 👍🎉 First off, thank you so much for investing your time in contributing to our project! 🎉👍 7 | 8 | The following is a set of guidelines for contributing to [Javascript-Interview-Preparation](https://github.com/Jaynil1611/Javascript-Interview-Preparation). 9 | In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR. These are mostly guidelines, not rules. 10 | Use your best judgment, and feel free to propose changes to this repository thorugh a pull request. 11 | 12 | Please note we have a [code of conduct](./CODE_OF_CONDUCT.md), please follow it in all your interactions with the project to keep our community approachable and respectable. 13 | 14 | Use the table of contents icon on the top left corner of this document to get to a specific section of this guide quickly. 15 | 16 | # How Can I Contribute? 17 | 18 | If you have any javascript, react or web fundamentals related question which you think can be added to this repository, then you can always raise a pull request describing the question in detail & if possible providing a working solution of the question. 19 | 20 | 21 | Pull requests are the best way to propose changes. We actively welcome your pull requests: 22 | 23 | 1. Fork the repo and create your branch from `master`. 24 | 2. If you've added new question, describe the question in detail & categorize it into repective folder (if present). 25 | 3. If you've added a working solution to the question, describe your solution 26 | 4. If possible attach an online editor link to the solution where maintainers can review it. 27 | 5. Issue that pull request! 28 | 29 | For further guidance about issuing a pull request, please refer to the below links: 30 | 31 | * [Pull Request Guidelines](/.github/pull_request_template.md) 32 | 33 | 34 | ## Any contributions you make will be under the MIT Software License 35 | 36 | In short, when you submit changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. 37 | 38 | 39 | ## Report issues/bugs using GitHub's [issues](https://github.com/Jaynil1611/Javascript-Interview-Preparation/issues) 40 | 41 | We use GitHub issues to track public bugs or feature requests. Report a bug or request for a feature by [opening a new issue](https://github.com/Jaynil1611/Javascript-Interview-Preparation/issues/new/choose); it's that easy! 42 | 43 | ### Bug Reports 44 | 45 | **Great Bug Reports** tend to have: 46 | 47 | - A quick summary and/or background 48 | - Steps to reproduce 49 | - Be specific! 50 | - Share the snapshot, if possible. 51 | - [CodeSandbox](https://codesandbox.io/) live link 52 | - What actually happens 53 | - What you expected would happen 54 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) 55 | 56 | People _love_ in-depth bug reports. 57 | 58 | ### Feature Request 59 | 60 | **Great Feature Requests** tend to have: 61 | 62 | - A quick idea summary 63 | - What & why you wanted to add the specific feature 64 | - Additional Context like images, links to resources to implement the feature etc. 65 | 66 | For further guidance about creating a new issue, please refer to the related links: 67 | 68 | * [Feature Request Guidelines](/.github/ISSUE_TEMPLATE/feature_request.md) 69 | * [Bug Report Guidelines](/.github/ISSUE_TEMPLATE/bug_report.md) 70 | 71 | 72 | ## Coding conventions 73 | 74 | In order to sanitize coding standards, please follow [this style guide](https://github.com/airbnb/javascript). 75 | 76 | # License 77 | By contributing, you agree that your contributions will be licensed under its [MIT License](./LICENSE). -------------------------------------------------------------------------------- /promises/promises.js: -------------------------------------------------------------------------------- 1 | const fakeFetch = (paramter, delay, value) => { 2 | return new Promise((resolve, reject) => { 3 | setTimeout(() => { 4 | paramter ? resolve(value) : reject(`Promise rejected! ${value}`) 5 | }, delay) 6 | }) 7 | } 8 | 9 | // function myPromiseAll(promises) { 10 | // let promiseResults = []; 11 | // let completedPromiseCount = 0; 12 | // return new Promise((resolve, reject) => { 13 | // promises.forEach(async (promise) => { 14 | // try { 15 | // const output = await promise; 16 | // promiseResults.push(output); 17 | // completedPromiseCount++; 18 | // if (completedPromiseCount === promises.length) { 19 | // resolve(promiseResults); 20 | // } 21 | // } catch (err) { 22 | // reject(err); 23 | // } 24 | // }) 25 | // }) 26 | // } 27 | 28 | function myPromiseAll(promises) { 29 | return new Promise((resolve, reject) => { 30 | let promiseResults = Array(promises.length); 31 | let completedPromiseCount = 0; 32 | promises.forEach(async (promise, index) => { 33 | try { 34 | promiseResults[index] = await promise; 35 | completedPromiseCount++; 36 | if (completedPromiseCount === promises.length) { 37 | resolve(promiseResults); 38 | } 39 | } catch (err) { 40 | reject(err); 41 | } 42 | }) 43 | }) 44 | } 45 | 46 | function myPromiseAllSync(promises) { 47 | return new Promise((resolve, reject) => { 48 | let promiseResults = []; 49 | const results = promises.reduce((result, promise) => { 50 | return result.then(() => { 51 | return promise.then((value) => { 52 | promiseResults.push(value); 53 | return promiseResults; 54 | }); 55 | }).catch(err => reject(err)); 56 | }, Promise.resolve()); 57 | resolve(results); 58 | }) 59 | } 60 | 61 | function myPromiseRace(promises) { 62 | return new Promise((resolve, reject) => { 63 | promises.forEach(async (promise) => { 64 | try { 65 | const output = await promise; 66 | resolve(output); 67 | } catch (err) { 68 | reject(err); 69 | } 70 | }) 71 | }) 72 | }; 73 | 74 | function myPromiseAny(promises) { 75 | let promiseResults = []; 76 | let rejectedPromiseCount = 0; 77 | return new Promise((resolve, reject) => { 78 | promises.forEach(async (promise) => { 79 | try { 80 | const output = await promise; 81 | resolve(output); 82 | } catch (err) { 83 | promiseResults.push(err); 84 | console.log(err); 85 | rejectedPromiseCount++; 86 | if (rejectedPromiseCount === promises.length) { 87 | reject(promiseResults); 88 | } 89 | } 90 | }) 91 | }) 92 | } 93 | 94 | const promise1 = new Promise((resolve, reject) => { 95 | setTimeout(resolve, 500, 'one'); 96 | }); 97 | 98 | const promise2 = new Promise((resolve, reject) => { 99 | setTimeout(resolve, 100, 'two'); 100 | }); 101 | 102 | function functionWrapper(...functions) { 103 | return new Promise((resolve, reject) => { 104 | let promiseResults = []; 105 | const results = functions.reduce((result, fn) => { 106 | return result.then(() => { 107 | return fn().then((value) => { 108 | promiseResults.push(value) 109 | return promiseResults; 110 | }); 111 | }).catch(err => reject(err)); 112 | }, Promise.resolve()); 113 | resolve(results); 114 | }) 115 | } 116 | 117 | const fakeFetch1 = () => fakeFetch(true, 300, 'p1'); 118 | const fakeFetch2 = () => fakeFetch(true, 100, 'p2'); 119 | 120 | // myPromiseAllSync([fakeFetch(true, 1000, 'p1'), fakeFetch(true, 500, 'p2')]).then(results => console.log(results)); 121 | 122 | // myPromiseRace([fakeFetch(true, 1000, 'p1'), fakeFetch(true, 500, 'p2')]).then(results => console.log(results)); 123 | 124 | // myPromiseAny([fakeFetch(false, 1000, 'p1'), fakeFetch(false, 500, 'p2')]).then(results => console.log(results)).catch(err => console.log(err)); 125 | 126 | functionWrapper(fakeFetch1, fakeFetch2).then(res => console.log(res)); --------------------------------------------------------------------------------