diff --git a/README.md b/README.md
index 24d6294..f6d53af 100644
--- a/README.md
+++ b/README.md
@@ -30,31 +30,50 @@
## JavaScript Modern Interview Code Challenges by topic
-- [Primitives](https://github.com/sadanandpai/javascript-code-challenges/blob/main/challenges/primitives.md#home)
+- Primitives
-- [Functions](https://github.com/sadanandpai/javascript-code-challenges/blob/main/challenges/functions.md#home)
+ - [Concepts](./challenges/primitives-concepts.md#home)
+ - [Challenges](./challenges/primitives-challenges.md#home)
-- [Objects](https://github.com/sadanandpai/javascript-code-challenges/blob/main/challenges/objects.md#home)
+- Functions
-- [Collections](https://github.com/sadanandpai/javascript-code-challenges/blob/main/challenges/collections.md#home)
+ - [Concepts](./challenges/functions-concepts.md#home)
+ - [Challenges](./challenges/functions-challenges.md#home)
-- [Asynchronousity](https://github.com/sadanandpai/javascript-code-challenges/blob/main/challenges/async.md#home)
+- Objects
+
+ - [Concepts](./challenges/objects-concepts.md#home)
+ - [Challenges](./challenges/objects-challenges.md#home)
+
+- Collections
+
+ - [Concepts](./challenges/collections-concepts.md#home)
+ - [Challenges](./challenges/collections-challenges.md#home)
+
+- Asynchronousity
+ - [Concepts](./challenges/async-concepts.md#home)
+ - [Challenges](./challenges/async-challenges.md#home)
---
### Usage Guide and Study materials
-If you want to know more about using this repo or view the list of recommended list of study materials on JavaScript, check out [Usage and Study Guide](https://github.com/sadanandpai/javascript-code-challenges/blob/main/usageAndStudyGuide.md)
+
+If you want to know more about using this repo or view the list of recommended list of study materials on JavaScript, check out [Usage and Study Guide](./usageAndStudyGuide.md)
### Contributing Guide
-If you want to contribute, improve or suggest changes to this repo, then check out the [Contributing Guide](https://github.com/sadanandpai/javascript-code-challenges/blob/main/contributing.md)
+
+If you want to contribute, improve or suggest changes to this repo, then check out the [Contributing Guide](./contributing.md)
### Stargazers
+
[](https://github.com/sadanandpai/javascript-code-challenges/stargazers)
### Forkers
+
[](https://github.com/sadanandpai/javascript-code-challenges/network/members)
### License
-This repository is MIT licensed. [Read more](https://github.com/sadanandpai/javascript-code-challenges/blob/main/LICENSE)
+
+This repository is MIT licensed. [Read more](./LICENSE)
diff --git a/challenges/async-challenges.md b/challenges/async-challenges.md
new file mode 100644
index 0000000..9e5bcf1
--- /dev/null
+++ b/challenges/async-challenges.md
@@ -0,0 +1,616 @@
+
+
+## JavaScript interview code challenges on Asynchronous programming - challenges
+
+1. [Print "Hello, world" with a delay of 3 seconds](#Q1)
+1. [Create a function which receives a function as argument and executes it after 2 seconds](#Q2)
+1. [Print numbers from 1 to 10 with delay of 1 second between each value being printed](#Q3)
+1. [Print numbers from 1 to 10 with delay of 1 second between each value being printed using setInterval](#Q4)
+1. [Print numbers from 10 to 1 with delay of 1 second between each value being printed using setTimeout using pre ES6 features only](#Q5)
+1. [Write a utility which prints numbers starting from an initial value and increment in steps which can be started and stopped by the user, any number of times](#Q6)
+1. [Execute an array of asynchronous functions one after the other in sequence using callbacks](#Q7)
+1. [Execute the given list of asynchronous functions in parallel and return the results as an array to the callback](#Q8)
+1. [Execute 3 asynchronous functions one after the other in sequence using promise chaining](#Q9)
+1. [Execute 3 asynchronous functions one after the other in sequence using async await](#Q10)
+1. [Execute 3 asynchronous functions one after the other in sequence using promise chaining and do not terminate on failure](#Q11)
+1. [Execute 3 asynchronous functions one after the other in sequence using async await and do not terminate on failure](#Q12)
+1. [Execute an array of asynchronous functions which returns a promise, one after the other in sequence](#Q13)
+1. [Execute an array of asynchronous functions simultaneously but print the output in the ordered sequence. Do not wait for printing the data if it already available after promise is settled](#Q14)
+1. [Design a utility which takes array of asynchronous functions and returns the 1st successful or non successful result with max waiting time set by the user](#Q15)
+1. [Design a utility which takes URL and a value for attempts which will attempt to make a fetch request. If on failure it tries again with increasing delay for number of times which user has requested](#Q16)
+1. [Create a generator to return a random number on every request](#Q17)
+1. [Search for the presence of a given value in the nested object using generator](#Q18)
+
+---
+
+#### Q1
+### Print "Hello, world" with a delay of 3 seconds
+
+- setTimeout takes a function as the 1st argument and optional timeout delay & list of values as the function parameters
+- setTimeout returns an id (number) which can be used to stop the setTimeout using clearTimeout function
+
+```js
+setTimeout(function (text) {
+ console.log(text);
+}, 3000, 'Hello, World');
+```
+
+```js
+setTimeout(() => console.log('Hello, World'), 3000);
+```
+
+```js
+setTimeout(console.log, 3000, 'Hello, World');
+```
+
+###### Notes
+Zero or more values that represent any parameters you want to pass to the function when it is run.
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals
+
+
+
+#### Q2
+### Create a function which receives a function as argument and executes it after 2 seconds
+
+```js
+function callbackExec(callback) {
+ if (typeof callback === 'function') {
+ setTimeout(() => {
+ callback();
+ console.log('Callback is executed after 2 seconds');
+ }, 2000);
+ }
+}
+
+function displayHello() {
+ console.log('Hello');
+}
+
+callbackExec(displayHello);
+```
+
+
+
+#### Q3
+### Print numbers from 1 to 10 with delay of 1 second between each value being printed
+
+```js
+const num1 = 1, num2 = 10;
+for (let i = num1; i <= num2; i++) {
+ setTimeout(() => console.log(i), i * 1000);
+}
+```
+
+```js
+const num1 = 1, num2 = 10;
++function displayWithDelay(i){
+ console.log(i);
+ if(i !== num2)
+ setTimeout(displayWithDelay, 1000, ++i);
+}(1);
+```
+
+###### Notes
+In the 2nd solution, recursive setTimeout is used.
+
+###### References
+- https://javascript.info/settimeout-setinterval
+
+
+
+#### Q4
+### Print numbers from 1 to 10 with delay of 1 second between each value being printed using setInterval
+
+- `setInterval` function repeats a block of code at every given timing event
+- `clearInterval` is used to stop the setInterval execution
+
+```js
+const num1 = 1, num2 = 10;
+let i = num1;
+const intervalId = setInterval(() => {
+ console.log(++i);
+ if (i === num2)
+ clearInterval(intervalId);
+}, 1000);
+```
+
+
+
+#### Q5
+### Print numbers from 10 to 1 with delay of 1 second between each value being printed using setTimeout using pre ES6 features only
+
+- We can use 3rd parameter of setTimeout to pass the value of iteration which creates a new scope each time loop iterates
+- We can also use an inner function scope (IIFE) within the for loop for each iteration
+
+```js
+var num1 = 10, num2 = 1;
+for (var i = num1; i >= num2; i--) {
+ setTimeout(console.log, (num1 - i) * 1000, i);
+}
+```
+
+```js
+var num1 = 10, num2 = 1;
+for (var i = num1; i >= num2; i--) {
+ (function (i) {
+ setTimeout(() => console.log(i), (num1 - i) * 1000);
+ })(i);
+}
+```
+
+###### References
+- https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/scope%20%26%20closures/ch5.md
+
+
+
+#### Q6
+### Write a utility which prints numbers starting from an initial value and increment in steps which can be started and stopped by the user, any number of times
+
+- The functionality to start and stop can be exposed from a function which internally takes care of incrementing and displaying data
+- `setInterval` can be used to achieve the task and handle the start & stop of data display
+
+```js
+function timer(init = 0, step = 1) {
+ var intervalId;
+ var count = init;
+
+ function startTimer() {
+ if (!intervalId){
+ intervalId = setInterval(() => {
+ console.log(count);
+ count += step;
+ }, 1000);
+ }
+ }
+
+ function stopTimer() {
+ clearInterval(intervalId);
+ intervalId = null;
+ }
+
+ return {
+ startTimer,
+ stopTimer,
+ };
+}
+
+// driver code
+const timerObj = timer(100, 10);
+timerObj.startTimer();
+setTimeout(() => {
+ timerObj.stopTimer();
+}, 5000);
+```
+
+###### Notes
+The function can also be modified to have completion after which timer can not be started
+
+
+
+#### Q7
+### Execute an array of asynchronous functions one after the other in sequence using callbacks
+
+- The asynchronous function can be simulated using setTimeout which executes the callback
+- The array of functions execution can be managed by having a function which takes care of execution of all the async functions
+- Asynchronous functions need not be aware of the function to be executed and will take a callback as argument and execute it after completion
+
+```js
+function asyncFunc1(callback) {
+ console.log('Started asyncFunc1');
+ setTimeout(() => {
+ console.log('Completed asyncFunc1');
+ callback();
+ }, 3000);
+}
+
+function asyncFunc2(callback) {
+ console.log('Started asyncFunc2');
+ setTimeout(() => {
+ console.log('Completed asyncFunc2');
+ callback();
+ }, 2000);
+}
+
+function asyncFunc3(callback) {
+ console.log('Started asyncFunc3');
+ setTimeout(() => {
+ console.log('Completed asyncFunc3');
+ callback();
+ }, 1000);
+}
+
+function callbackManager(asyncFuncs) {
+ function nextFuncExecutor() {
+ const nextAsyncFunc = asyncFuncs.shift();
+ if (nextAsyncFunc && typeof nextAsyncFunc === 'function') {
+ nextAsyncFunc(nextFuncExecutor, asyncFuncs);
+ }
+ }
+ nextFuncExecutor();
+}
+
+// driver code
+callbackManager([asyncFunc1, asyncFunc2, asyncFunc3]);
+```
+
+###### Notes
+3 asynchrounous functions are considered here, but the program should work for any number
+
+
+
+#### Q8
+### Execute the given list of asynchronous functions in parallel and return the results as an array to the callback
+```js
+// Example
+function asyncFunc1(callback) {
+ setTimeout(() => {
+ callback(1);
+ }, 3000);
+}
+
+function asyncFunc2(callback) {
+ setTimeout(() => {
+ callback(2);
+ }, 2000);
+}
+
+function asyncFunc3(callback) {
+ setTimeout(() => {
+ callback(3);
+ }, 1000);
+}
+
+asyncParallel([asyncFunc1, asyncFunc2, asyncFunc3], result => {
+ console.log(result); // 1, 2, 3 (prints results of each asynchronous function in order)
+});
+```
+
+- The async functions can be executed in parallel using the loop and can be tracked for completion with a counter
+- The callback function can be sent to the async functions and the results will be stored in the array which will be returned after the completion of all
+
+```js
+function asyncParallel(asyncFuncArr, callback) {
+ const resultArr = new Array(asyncFuncArr.length);
+ let resultCounter = 0;
+
+ asyncFuncArr.forEach((async, index) => {
+ async(value => {
+ resultArr[index] = value;
+ resultCounter++;
+ if (resultCounter >= asyncFuncArr.length) {
+ callback(resultArr);
+ }
+ });
+ });
+}
+```
+
+###### References
+- https://jsvault.com/async-parallel
+
+
+
+#### Q9
+### Execute 3 asynchronous functions one after the other in sequence using promise chaining
+
+- The implementation of chaining is that the result is passed through the chain of `then` handlers for all the promises
+- `then` method on Promise also returns a promise which can be used to perform `then` on the returned promise
+- The errors in promise / promise chaining can be handled with the error callback for each promise when it settles or with a generic catch block
+
+```js
+asyncFunc1().then(
+ () => {
+ console.log('Completed async1');
+ asyncFunc2().then(
+ () => {
+ console.log('Completed async2');
+ asyncFunc3().then(
+ () => {
+ console.log('Completed async3');
+ console.log('All succeeded');
+ },
+ (err) => {
+ console.log('Failure in ' + err);
+ }
+ );
+ },
+ (err) => {
+ console.log('Failure in ' + err);
+ }
+ );
+ },
+ (err) => {
+ console.log('Failure in ' + err);
+ }
+);
+```
+
+```js
+asyncFunc1()
+.then(asyncFunc2)
+.then(asyncFunc3)
+.catch(() => { console.log("Error occured in one of the async function"); });
+```
+
+###### Notes
+If `then` method has a return statement which is a promise then it will be considered for the next promise chain until it settles
+
+###### References
+- https://javascript.info/promise-chaining
+
+
+
+#### Q10
+### Execute 3 asynchronous functions one after the other in sequence using async await
+
+- Async function with `await` for each promise can be used to execute in sequence
+
+```js
++async function executor(){
+ try{
+ await asyncFunc1();
+ await asyncFunc2();
+ await asyncFunc3();
+ console.log('All succeeded');
+ }
+ catch(){
+ console.log("Error occured);
+ }
+}();
+```
+
+
+
+#### Q11
+### Execute 3 asynchronous functions one after the other in sequence using promise chaining and do not terminate on failure
+
+- The promise which gets rejected will invoke the 2nd function argument to `then` handler
+- The failure handler will receive the error and continue with next execution which will not propagate failures
+
+```js
+async1()
+ .then(
+ () => {
+ console.log('Async1 success');
+ },
+ () => {
+ console.log('Async1 failure');
+ }
+ )
+ .then(async2)
+ .then(
+ () => {
+ console.log('Async2 success');
+ },
+ () => {
+ console.log('Async2 failure');
+ }
+ )
+ .then(async3)
+ .then(
+ () => {
+ console.log('Async3 success');
+ },
+ () => {
+ console.log('Async3 failure');
+ }
+ );
+```
+
+
+
+#### Q12
+### Execute 3 asynchronous functions one after the other in sequence using async await and do not terminate on failure
+
+- Unlike promises, `try-catch` block can be used on async functions
+- `catch` block for each asynchronous function can be used to catch errors and continue with next execution which will not propagate failures
+
+```js
++(async function executor() {
+ try {
+ await asyncFunc1();
+ console.log('Async1 success');
+ } catch {
+ console.log('Async1 failure');
+ }
+ try {
+ await asyncFunc2();
+ console.log('Async2 success');
+ } catch {
+ console.log('Async2 failure');
+ }
+ try {
+ await asyncFunc3();
+ console.log('Async3 success');
+ } catch {
+ console.log('Async3 failure');
+ }
+ console.log('All succeeded');
+})();
+```
+
+
+
+#### Q13
+### Execute an array of asynchronous functions which returns a promise, one after the other in sequence
+
+- Asynchronous functions can be executed and promises can be captured in an array
+- Array method `reduce` can be used to make the sequential execution on promise settlement
+
+```js
+const asyncFuncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
+
+asyncFuncArr.reduce((acc, async) => {
+ return acc.then(() => async().then(console.log));
+}, Promise.resolve());
+```
+
+```js
+const asyncFuncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
+
+asyncFuncArr.reduce(async (acc, asyncFunc) => {
+ await acc;
+ console.log(await asyncFunc());
+}, Promise.resolve());
+```
+
+###### Notes
+`Promise.resolve()` is used as the initial value to `reduce`, which resolves the promise immediately,
+
+
+
+#### Q14
+### Execute an array of asynchronous functions simultaneously but print the output in the ordered sequence. Do not wait for printing the data if it already available after promise is settled
+
+- Array method `reduce` can be used to make the simultaneously execution on promise settlement
+- Unlike sequential execution, the parallel execution of asynchronous functions happen but the output will executed in order of sequence
+
+```js
+const asyncFuncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
+
+asyncFuncArr
+.map(async => async())
+.reduce((acc, promise) => {
+ return acc.then(() => promise).then(data => console.log(data));
+}, Promise.resolve());
+```
+
+```js
+const asyncFuncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
+
+asyncFuncArr
+.map(async => async())
+.reduce(async (acc, promise) => {
+ console.log(await acc.then(() => promise));
+}, Promise.resolve());
+```
+
+
+
+#### Q15
+### Design a utility which takes array of asynchronous functions and returns the 1st successful or non successful result with max waiting time set by the user
+
+- `Promise.race` is an in built JavaScript method which helps us to return the first resolved or rejected promise data from promises array
+- Timeout feature can be set by adding a function returning a promise which rejects after specified amount of time
+- If any promise resolves before timeout the promise which settles first will be the output else timeout will cause rejection
+
+```js
+function timeoutFunc() {
+ const delay = 500;
+ return new Promise((resolve, reject) => {
+ setTimeout(() => reject("Timeout"), delay));
+ }
+}
+
+const asyncArr = [asyncFunc1, asyncFunc2, asyncFunc3, timeoutFunc];
+const promiseArr = asyncArr.map(asyncFunc => asyncFunc());
+Promise.race(promiseArr).then(console.log).catch(console.log);
+```
+
+
+
+#### Q16
+### Design a utility which takes URL and a value for attempts which will attempt to make a fetch request. If on failure it tries again with increasing delay for number of times which user has requested
+
+- Utility can designed which returns a promise which attempts to make requests and return the data on success
+- The `fetch` request attempts to make calls after increasing time delay on failure
+- If all the attempts by to get response fails, promise gets rejected
+
+```js
+function requestManager(url, attempts = 3) {
+ return new Promise(async (resolve, reject) => {
+ for (let i = 0; i < attempts; i++) {
+ try {
+ const response = await fetch(url);
+ resolve(response);
+ break;
+ } catch (err) {
+ if (attempts - 1 === i) {
+ reject(err);
+ break;
+ }
+ await new Promise(resolve => setTimeout(resolve, 1000 + 1000 * i));
+ }
+ }
+ });
+}
+
+// driver code
+requestManager('https://reqbin.com/echo/get/json', 3).then(
+ response => console.log(response),
+ error => console.log(error)
+);
+```
+
+###### Notes
+`1000 + 1000 * i` is used for delay after 1st unsuccessful attempt to fetch, which increases the delay on every iteration
+
+###### References
+- https://dev.to/ycmjason/javascript-fetch-retry-upon-failure-3p6g
+
+
+
+#### Q17
+### Create a generator to return a random number on every request
+
+- The generation of random number can be implemented in the normal way in the function but will returned and function yields
+- The function will again continue to execute in loop to return a new random number
+
+```js
+function* generatorFunc(param){
+ while(true){
+ yield Math.ceil(Math.random() * 100);
+ }
+}
+
+// driver code
+const it = generatorFunc();
+const rand1 = it.next();
+const rand2 = it.next();
+```
+
+###### Notes
+Genertor function need not complete its execution
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
+
+
+
+#### Q18
+### Search for the presence of a given value in the nested object using generator
+
+- With the help of generator Inversion of control is possible
+- Instead of function seaching for the key by passing the callback or key, the logic can be implemented in the controlling code
+- For..of loop calling the recursive generator function on object can be used to achieve this
+
+```js
+function* objectReader(obj){
+ for(let key in obj){
+ if(typeof obj[key] === "object"){
+ yield *objectReader(obj[key]);
+ }
+ else{
+ yield obj[key];
+ }
+ }
+}
+
+// driver code
+const it = objectReader({a: 1, b: 2, c: 3, d: { x: 4, y: 5, z: {m: 6, b: 7}}});
+const searchValue = 5;
+
+for(let value of it){
+ if(value === searchValue) {
+ console.log(searchValue + " exists");
+ }
+}
+```
+
+
+
+[[↑] Back to top](#home)
diff --git a/challenges/async-concepts.md b/challenges/async-concepts.md
new file mode 100644
index 0000000..4b167f5
--- /dev/null
+++ b/challenges/async-concepts.md
@@ -0,0 +1,657 @@
+
+
+## JavaScript interview code challenges on Asynchronous programming - concpets
+
+1. [Show the execution of 3 asynchronous block of code, one after the other in sequence](#Q1)
+1. [Write a code to make xmlHTTPRequest to get data from the server asynchronously](#Q2)
+1. [Show the working of promise along with resolve & reject code](#Q3)
+1. [Wrap the setTimeout function to convert to a promise](#Q4)
+1. [Convert the xmlHTTPRequest to promise based function to get the data from the server asynchronously (fetch)](#Q5)
+1. [Make a fetch request to retrieve and store JSON data from server](#Q6)
+1. [Cancel a fetch request](#Q7)
+1. [Show the working of async await work with promises](#Q8)
+1. [Write a code to resolve all the list of asynchronous executions of promises and stop if any of them is rejected. Print the output accordingly](#Q9)
+1. [Write a code to resolve all the list of asynchronous executions of promises no matter if each execution succeeds or fails. Print the output of each](#Q10)
+1. [Explain the working of Promise.race with few asynchronous function example](#Q11)
+1. [Show me the working of a generator function](#Q12)
+1. [Write a generator function which uses another generator function internally to fetch the values. Use for..of loop to consume the values](#Q13)
+1. [Write an interface to mock Promise in JavaScript which can be called to create a promise with resolve and reject. Also implement then functionality](#Q14)
+1. [Write a function which helps to achieve the `Promise.all` functionality using promises](#Q15)
+1. [Show the working generator function with promises](#Q16)
+
+---
+
+#### Q1
+### Show the execution of 3 asynchronous block of code, one after the other in sequence
+
+- The asynchronous block of code can be a function which executes asynchronously
+- The execution of such function can be simulated using setTimeout to with delay and execute different blocks of code inside each
+
+```js
+function asyncFunc() {
+ console.log('Started asyncFunc1');
+ //Async1 code
+ setTimeout(() => {
+ console.log('Completed asyncFunc1');
+
+ console.log('Started asyncFunc2');
+ //Async2 code
+ setTimeout(() => {
+ console.log('Completed asyncFunc2');
+
+ console.log('Started asyncFunc3');
+ //Async3 function code
+ setTimeout(() => {
+ console.log('Completed asyncFunc3');
+ }, 1000);
+ }, 2000);
+ }, 3000);
+}
+
+asyncFunc();
+```
+
+###### Notes
+The nested blocks of statements shown in the comments which get executed one after the other in sequence
+
+
+
+#### Q2
+### Write a code to make xmlHTTPRequest to get data from the server asynchronously
+
+- XMLHttpRequest (XHR) objects are used to interact with server to retrieve data from a URL without having to do a full page refresh
+- XHR requests can be initiated by creating the object and providing the arguments such as 'method', url etc
+- The success and failure of the request can be managed by callbacks
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.open("GET", url);
+
+xhr.onload = function() {
+ console.log(this.response);
+};
+
+xhr.onerror = function() {
+ console.log(this.statusText);
+};
+
+xhr.send();
+```
+
+###### Notes
+XHR is used mainly in AJAX programming
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
+
+
+
+#### Q3
+### Show the working of promise along with resolve & reject code
+
+- The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value
+- Promise returns an object which ramains in pending state until it is resolved or rejected
+- Promise takes a function as an argument called as 'resolver' which can have resolve and reject as parameters
+- Resolve call will resolve the promise and reject will reject the promise (passing data is optional)
+- `then` method on promise object is used to execute the user code after promise settles, which takes functions where 1st one is for success and 2nd for failure
+- Functions with success and failure of the promises are used to illustrate the basics of promise code
+
+```js
+function asyncResolveFunc() {
+ function resolver(resolve, reject) {
+ resolve('Success');
+ }
+ return new Promise(resolver);
+}
+
+function asyncRejectFunc() {
+ function resolver(resolve, reject) {
+ reject('Failure');
+ }
+ return new Promise(resolver);
+}
+
+// driver code
+const promiseSuccess = asyncResolveFunc();
+const promiseFailure = asyncRejectFunc();
+
+// Succeeded promise .then executes first function passed as argument
+promiseSuccess.then((successData) => { console.log(successData); }, (failureData) => { console.log(failureData); });
+
+// Failed promise .then executes second function passed as argument
+promiseFailure.then((successData) => { console.log(successData); }, (failureData) => { console.log(failureData); });
+```
+
+###### Notes
+Once the promise is resolved or rejected, status will not change
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
+
+
+
+#### Q4
+### Wrap the setTimeout function to convert to a promise
+
+- Promise can be used to wrap the `setTimeout` to make the code more readable
+- Function can take delay as argument and return a promise which gets resolved after timeout is complete
+
+```js
+function setTimeoutPromise(delay) {
+ function resolver(resolve) {
+ setTimeout(resolve(), delay);
+ }
+ return new Promise(resolver);
+}
+
+// driver code
+console.log('Task started');
+const timeoutPromise = setTimeoutPromise(3000);
+timeoutPromise.then(() => {
+ console.log('Task completed');
+});
+```
+
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
+
+
+
+#### Q5
+### Convert the xmlHTTPRequest to promise based function to get the data from the server asynchronously (fetch)
+
+- The Promise can be used to wrap the XHR request and provide cleaner interface to user for AJAX requests
+- Success and failure of the XHR request can be handled to resolve or reject the promise respectively
+
+```js
+function fetchData(url) {
+ return new Promise((resolve, reject) => {
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", url);
+
+ xhr.onload = function() {
+ try {
+ if(this.status === 200 ){
+ resolve(this);
+ } else{
+ reject(this);
+ }
+ } catch(e){
+ reject(e);
+ }
+ };
+
+ xhr.onerror = function() {
+ reject(this);
+ };
+
+ xhr.send();
+ });
+}
+
+// driver code
+fetchData("https://reqbin.com/echo/get/json")
+.then(data => {
+ console.log(data);
+})
+.catch(err => console.log(err));
+```
+
+###### Notes
+XHR reuqest is no more in use and all the modern browsers use `fetch` API which is based on promise
+
+###### References
+- https://medium.com/@RistaSB/create-ajax-function-with-xmlhttprequest-and-promise-fe7422e38b50
+
+
+
+#### Q6
+### Make a fetch request to retrieve and store JSON data from server
+
+- Fetch API is provided by the browser which returns a promise
+- Fetch takes url as the 1st argument and an object with request details as 2nd optional argument
+- Response is a streamable object and hence we will have to invoke JSON / text method on it which returns promise which settles to the data
+
+```js
+const response = fetch('https://reqbin.com/echo/get/json', {
+ method: 'GET', // *GET, POST, PUT, DELETE, etc
+ headers: {
+ 'Content-Type': 'application/json', // header
+ },
+});
+
+// driver code
+response.then(response => {
+ const responseData = response.json();
+ responseData.then(data => {
+ console.log(data);
+ });
+})
+.catch(err => {
+ console.log(err);
+});
+
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
+
+
+
+#### Q7
+### Cancel a fetch request
+
+- `AbortController` is an interface which can be used to abort a fetch request
+- `signal` object of the AbortController object can be used as the part of the argument to `fetch` and abort on controller object can be used to stop the request
+
+```js
+const controller = new AbortController();
+var signal = controller.signal;
+
+fetch(url, { signal }).then(response => {
+ console.log(response);
+}).catch(err => {
+ console.warn(err);
+});
+
+controller.abort();
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort
+- https://davidwalsh.name/cancel-fetch
+
+
+
+#### Q8
+### Show the working of async await work with promises
+
+- `async` functions are asynchronous functions in which the asynchrous code can be executed in synchronous looking manner using `await`
+- `await` expects a promise and the execution will stop until the promise is resolved
+- If promise gets rejected, error is thrown with failure reason which can be handled using simple try-catch block
+
+```js
+async function asyncAwaitFunc() {
+ try {
+ console.log('Executes normally when invoked');
+ await promiseReturningFunc();
+ console.log('Continues the execution after promise resolution');
+ } catch (err) {
+ console.log('Error occured: ' + err);
+ }
+}
+```
+
+###### Notes
+`await` keyword can only be used in a `async` function
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
+- https://javascript.info/async-await
+
+
+
+#### Q9
+### Write a code to resolve all the list of asynchronous executions of promises and stop if any of them is rejected. Print the output accordingly
+
+- `Promise.all` is the method which helps to achieve the functionality which settles if all the promises are resolved or any of them are rejected
+- It receives array of promises as an argument to it
+- Array of results will be the success data if all the promises resolves or the error data on failure of the first one
+
+```js
+const asyncArr = [async1, async2, async3];
+const promiseArr = asyncArr.map(async => async());
+
+finalResolution = Promise.all(promiseArr);
+finalResolution.then((output) =>{
+ for(let data of output) {
+ console.log(data);
+ }
+})
+.catch(err =>
+ console.log(err)
+);
+```
+
+```js
+const asyncArr = [async1, async2, async3];
+const promiseArr = asyncArr.map(async => async());
+
+(async function () {
+ try {
+ output = await Promise.all(promiseArr);
+ for (let data of output) {
+ console.log(data);
+ }
+ } catch (err) {
+ console.log(err);
+ }
+})();
+```
+
+###### Notes
+On failure of one of the promise, rest of the pending promises will be cancelled
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
+
+
+
+#### Q10
+### Write a code to resolve all the list of asynchronous executions of promises no matter if each execution succeeds or fails. Print the output of each
+
+- `Promise.allSettled` is the method which helps to achieve the functionality which completes after all promises settle no matter of failures
+- It receives array of promises as an argument to it
+- Array of results will be the output after completion of all promises with status as 'fulfilled' or 'rejected'
+
+```js
+const asyncArr = [async1, async2, async3];
+const promiseArr = asyncArr.map(async => async());
+finalResolution = Promise.allSettled(promiseArr);
+finalResolution
+ .then(output => {
+ for (let data of output) {
+ if (data.status === 'fulfilled') console.log(data.status + ': ' + data.value);
+ else if (data.status === 'rejected') console.log(data.status + ': ' + data.reason);
+ }
+ })
+ .catch(err => {
+ console.log(err);
+ });
+```
+
+```js
+const asyncArr = [async1, async2, async3];
+const promiseArr = asyncArr.map(async => async());
+(async function () {
+ try {
+ output = await Promise.allSettled(promiseArr);
+ for (let data of output) {
+ if (data.status === 'fulfilled') console.log(data.status + ': ' + data.value);
+ else if (data.status === 'rejected') console.log(data.status + ': ' + data.reason);
+ }
+ } catch (err) {
+ console.log(err);
+ }
+})();
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
+- https://davidwalsh.name/promise-allsettled
+
+
+
+#### Q11
+### Explain the working of Promise.race with few asynchronous function example
+
+- The `Promise.race` method returns a promise that fulfills or rejects as soon as one of the promises fulfills or rejects, with the success or failure
+
+```js
+function asyncFunc1() {
+ return new Promise(resolve =>
+ setTimeout(() => {
+ resolve('Resolved async1');
+ }, 2000)
+ );
+}
+
+function asyncFunc2() {
+ return new Promise(resolve =>
+ setTimeout(() => {
+ resolve('Resolved async2');
+ }, 3000)
+ );
+}
+
+function asyncFunc3() {
+ return new Promise((resolve, reject) =>
+ setTimeout(() => {
+ reject('Rejected async3');
+ }, 1000)
+ );
+}
+
+// driver code
+const asyncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
+const promiseArr = asyncArr.map(async => async());
+Promise.race(promiseArr).then(console.log).catch(console.log); // Rejected async3 (catch block)
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race
+
+
+
+#### Q12
+### Show me the working of a generator function
+
+- Generators are functions that can be exited and later re-entered
+- Generator function will have `*` after the keyword `function`
+- Generator when called returns an `iterator` which can be used to call `next` on it
+- `yield` keyword can be used inside such a function and stops the execution
+
+```js
+function* generatorFunc(param){
+ const num1 = yield;
+ const num2 = yield;
+ return num1 + num2;
+}
+
+// driver code
+const it = generatorFunc();
+it.next(); // { value: undefined, done: false}
+it.next(3); // { value: undefined, done: false}
+const sum = it.next(5); // { value: 8, done: true }
+sum.value; // 8
+```
+
+###### Notes
+Data between generator and iterator can be passed in both direction
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
+
+
+
+#### Q13
+### Write a generator function which uses another generator function internally to fetch the values. Use for..of loop to consume the values
+
+- Generator with the generator can be used to fetch the values using `yield*`
+- The code consuming the parent generator need to be aware of it and can be used directly
+- As the generator return iterator, for..of loop can be used on generator
+
+```js
+function* gen1() {
+ yield 1;
+ yield* gen2();
+ yield 4;
+}
+
+function* gen2() {
+ yield 2;
+ yield 3;
+}
+
+// driver code
+for (let value of gen1()) {
+ console.log(value);
+}
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
+
+
+
+#### Q14
+### Write an interface to mock Promise in JavaScript which can be called to create a promise with resolve and reject. Also implement then functionality
+
+- Basic promise interface will allow creation of promise by passing resolver as the argument
+- `resolve` and `reject` methods will have to be passed to the resolver which the user code will ivoke with data once settled
+- `setTimeout` with zero delay can be used to not immediately execute the resolver
+- List of callbacks to `then` to be invoked can be stores in the array of success and failure list
+- Once resolved or rejected, promise cannot change the state
+
+```js
+function MyPromise(resolver) {
+ let successList = [];
+ let failureList = [];
+ let resolution = 'pending';
+ let data;
+
+ function resolve(value) {
+ if (resolution === 'pending') {
+ for (let successCb of successList) {
+ successCb(value);
+ }
+ resolution = 'resolved';
+ data = value;
+ }
+ }
+
+ function reject(value) {
+ if (resolution === 'pending') {
+ for (let failureCb of failureList) {
+ failureCb(value);
+ }
+ resolution = 'rejected';
+ data = value;
+ }
+ }
+
+ setTimeout(() => {
+ try {
+ resolver(resolve, reject);
+ } catch (err) {
+ reject(err);
+ }
+ }, 0);
+
+ return {
+ status: resolution,
+ then: function (onSuccess, onFailure) {
+ if (resolution === 'pending') {
+ successList.push(onSuccess);
+ failureList.push(onFailure);
+ } else {
+ resolution === 'resolved' ? onSuccess(data) : onFailure(data);
+ }
+ },
+ };
+}
+
+// driver code
+let p = new MyPromise((resolve, reject) => {
+ resolve(10);
+});
+
+p.then(data => console.log(data), console.log);
+```
+
+###### Notes
+ES6 Promise is much more complex and sophesticated than the above shown implementation.
+
+
+
+#### Q15
+### Write a function which helps to achieve the `Promise.all` functionality using promises
+
+- `Promise.all` method is fail fast procedure to return all the promise resolved data in array or failed reason
+
+```js
+function PromiseAll(promiseArr) {
+ return new Promise((resolve, reject) => {
+ const dataArr = new Array(promiseArr.length);
+ let resolution = 'pending';
+
+ for (let index in promiseArr) {
+ promiseArr[index].then(
+ data => {
+ if (resolution === 'pending') {
+ dataArr[index] = {
+ value: data,
+ status: 'fulfilled',
+ };
+ if (!dataArr.includes(undefined)) {
+ resolution = 'fulfilled';
+
+ resolve(dataArr);
+ }
+ }
+ },
+ err => {
+ if (resolution === 'pending') {
+ resolution = 'rejected';
+ reject({
+ reason: err,
+ status: 'rejected',
+ });
+ }
+ }
+ );
+ }
+ });
+}
+
+// driver code
+PromiseAll([
+ new Promise(resolve => setTimeout(resolve, 1000)),
+ new Promise((resolve, reject) => setTimeout(reject, 2000)),
+]).then(console.log, console.log);
+```
+
+
+
+#### Q16
+### Show the working generator function with promises
+
+- Generator can be used with promises where yield will return a promise and promise resolution can trigger continuation
+- Helper function is used to manage this flow which takes generator function as an argument and executes it
+
+```js
+// asynchronous helper function returning a promise which gets resolved after the specified delay with data
+function asyncFunc(data, delay){
+ return new Promise(resolve => setTimeout(resolve, delay, data));
+}
+
+function* gen() {
+ // async function calls to yield promise
+ const num1 = yield asyncFunc(2, 1000);
+ const num2 = yield asyncFunc(1, 2000);
+ console.log(num1 + num2); // 3 (2 + 1)
+}
+
+function executeGeneratorWithPromise(gen) {
+ const it = gen();
+
+ // takes input as promise from generator
+ function handle(promise) {
+ if (!promise.done)
+ promise.value
+ .then(data => {
+ // continue the execution of generator after promise is resolved
+ handle(it.next(data));
+ })
+ .catch(err => iterator.throw(err));
+ }
+
+ handle(it.next());
+}
+
+// call generator executor function and pass generator function reference
+executeGeneratorWithPromise(gen);
+```
+
+###### Notes
+The generator and the helper function 'executeGeneratorWithPromise' executes hand in hand, where the generator pauses returning a promise and the helper function starts generator on that promise resolution
+
+###### References
+- https://www.promisejs.org/generators/
+
+
+
+[[↑] Back to top](#home)
diff --git a/challenges/async.md b/challenges/async.md
deleted file mode 100644
index 672bc74..0000000
--- a/challenges/async.md
+++ /dev/null
@@ -1,1263 +0,0 @@
-
-
-## JavaScript interview code challenges on Asynchronous programming
-
-1. [Print "Hello, world" with a delay of 3 seconds](#Q1)
-2. [Create a function which receives a function as argument and executes it after 2 seconds](#Q2)
-3. [Print numbers from 1 to 10 with delay of 1 second between each value being printed](#Q3)
-4. [Print numbers from 1 to 10 with delay of 1 second between each value being printed using setInterval](#Q4)
-5. [Print numbers from 10 to 1 with delay of 1 second between each value being printed using setTimeout using pre ES6 features only](#Q5)
-6. [Show the execution of 3 asynchronous block of code, one after the other in sequence](#Q6)
-7. [Write a utility which prints numbers starting from an initial value and increment in steps which can be started and stopped by the user, any number of times](#Q7)
-8. [Execute an array of asynchronous functions one after the other in sequence using callbacks](#Q8)
-9. [Execute the given list of asynchronous functions in parallel and return the results as an array to the callback](#39)
-10. [Write a code to make xmlHTTPRequest to get data from the server asynchronously](#Q10)
-11. [Show the working of promise along with resolve & reject code](#Q11)
-12. [Wrap the setTimeout function to convert to a promise](#Q12)
-13. [Convert the xmlHTTPRequest to promise based function to get the data from the server asynchronously (fetch)](#Q13)
-14. [Make a fetch request to retrieve and store JSON data from server](#Q14)
-15. [Cancel a fetch request](#Q15)
-16. [Execute 3 asynchronous functions one after the other in sequence using promise chaining](#Q16)
-17. [Show the working of async await work with promises](#Q17)
-18. [Execute 3 asynchronous functions one after the other in sequence using async await](#Q18)
-19. [Execute 3 asynchronous functions one after the other in sequence using promise chaining and do not terminate on failure](#Q19)
-20. [Execute 3 asynchronous functions one after the other in sequence using async await and do not terminate on failure](#Q20)
-21. [Execute an array of asynchronous functions which returns a promise, one after the other in sequence](#Q21)
-22. [Execute an array of asynchronous functions simultaneously but print the output in the ordered sequence. Do not wait for printing the data if it already available after promise is settled](#Q22)
-23. [Write a code to resolve all the list of asynchronous executions of promises and stop if any of them is rejected. Print the output accordingly](#Q23)
-24. [Write a code to resolve all the list of asynchronous executions of promises no matter if each execution succeeds or fails. Print the output of each](#Q24)
-25. [Explain the working of Promise.race with few asynchronous function example](#Q25)
-26. [Design a utility which takes array of asynchronous functions and returns the 1st successful or non successful result with max waiting time set by the user](#Q26)
-27. [Design a utility which takes URL and a value for attempts which will attempt to make a fetch request. If on failure it tries again with increasing delay for number of times which user has requested](#Q27)
-28. [Show me the working of a generator function](#Q28)
-29. [Create a generator to return a random number on every request](#Q29)
-30. [Write a generator function which uses another generator function internally to fetch the values. Use for..of loop to consume the values](#Q30)
-31. [Search for the presence of a given value in the nested object using generator](#Q31)
-32. [Write an interface to mock Promise in JavaScript which can be called to create a promise with resolve and reject. Also implement then functionality](#Q32)
-33. [Write a function which helps to achieve the `Promise.all` functionality using promises](#Q33)
-34. [Show the working generator function with promises](#Q34)
-
----
-
-#### Q1
-### Print "Hello, world" with a delay of 3 seconds
-
-- setTimeout takes a function as the 1st argument and optional timeout delay & list of values as the function parameters
-- setTimeout returns an id (number) which can be used to stop the setTimeout using clearTimeout function
-
-```js
-setTimeout(function (text) {
- console.log(text);
-}, 3000, 'Hello, World');
-```
-
-```js
-setTimeout(() => console.log('Hello, World'), 3000);
-```
-
-```js
-setTimeout(console.log, 3000, 'Hello, World');
-```
-
-###### Notes
-Zero or more values that represent any parameters you want to pass to the function when it is run.
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals
-
-
-
-#### Q2
-### Create a function which receives a function as argument and executes it after 2 seconds
-
-```js
-function callbackExec(callback) {
- if (typeof callback === 'function') {
- setTimeout(() => {
- callback();
- console.log('Callback is executed after 2 seconds');
- }, 2000);
- }
-}
-
-function displayHello() {
- console.log('Hello');
-}
-
-callbackExec(displayHello);
-```
-
-
-
-#### Q3
-### Print numbers from 1 to 10 with delay of 1 second between each value being printed
-
-```js
-const num1 = 1, num2 = 10;
-for (let i = num1; i <= num2; i++) {
- setTimeout(() => console.log(i), i * 1000);
-}
-```
-
-```js
-const num1 = 1, num2 = 10;
-+function displayWithDelay(i){
- console.log(i);
- if(i !== num2)
- setTimeout(displayWithDelay, 1000, ++i);
-}(1);
-```
-
-###### Notes
-In the 2nd solution, recursive setTimeout is used.
-
-###### References
-- https://javascript.info/settimeout-setinterval
-
-
-
-#### Q4
-### Print numbers from 1 to 10 with delay of 1 second between each value being printed using setInterval
-
-- `setInterval` function repeats a block of code at every given timing event
-- `clearInterval` is used to stop the setInterval execution
-
-```js
-const num1 = 1, num2 = 10;
-let i = num1;
-const intervalId = setInterval(() => {
- console.log(++i);
- if (i === num2)
- clearInterval(intervalId);
-}, 1000);
-```
-
-
-
-#### Q5
-### Print numbers from 10 to 1 with delay of 1 second between each value being printed using setTimeout using pre ES6 features only
-
-- We can use 3rd parameter of setTimeout to pass the value of iteration which creates a new scope each time loop iterates
-- We can also use an inner function scope (IIFE) within the for loop for each iteration
-
-```js
-var num1 = 10, num2 = 1;
-for (var i = num1; i >= num2; i--) {
- setTimeout(console.log, (num1 - i) * 1000, i);
-}
-```
-
-```js
-var num1 = 10, num2 = 1;
-for (var i = num1; i >= num2; i--) {
- (function (i) {
- setTimeout(() => console.log(i), (num1 - i) * 1000);
- })(i);
-}
-```
-
-###### References
-- https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/scope%20%26%20closures/ch5.md
-
-
-
-#### Q6
-### Show the execution of 3 asynchronous block of code, one after the other in sequence
-
-- The asynchronous block of code can be a function which executes asynchronously
-- The execution of such function can be simulated using setTimeout to with delay and execute different blocks of code inside each
-
-```js
-function asyncFunc() {
- console.log('Started asyncFunc1');
- //Async1 code
- setTimeout(() => {
- console.log('Completed asyncFunc1');
-
- console.log('Started asyncFunc2');
- //Async2 code
- setTimeout(() => {
- console.log('Completed asyncFunc2');
-
- console.log('Started asyncFunc3');
- //Async3 function code
- setTimeout(() => {
- console.log('Completed asyncFunc3');
- }, 1000);
- }, 2000);
- }, 3000);
-}
-
-asyncFunc();
-```
-
-###### Notes
-The nested blocks of statements shown in the comments which get executed one after the other in sequence
-
-
-
-#### Q7
-### Write a utility which prints numbers starting from an initial value and increment in steps which can be started and stopped by the user, any number of times
-
-- The functionality to start and stop can be exposed from a function which internally takes care of incrementing and displaying data
-- `setInterval` can be used to achieve the task and handle the start & stop of data display
-
-```js
-function timer(init = 0, step = 1) {
- var intervalId;
- var count = init;
-
- function startTimer() {
- if (!intervalId){
- intervalId = setInterval(() => {
- console.log(count);
- count += step;
- }, 1000);
- }
- }
-
- function stopTimer() {
- clearInterval(intervalId);
- intervalId = null;
- }
-
- return {
- startTimer,
- stopTimer,
- };
-}
-
-// driver code
-const timerObj = timer(100, 10);
-timerObj.startTimer();
-setTimeout(() => {
- timerObj.stopTimer();
-}, 5000);
-```
-
-###### Notes
-The function can also be modified to have completion after which timer can not be started
-
-
-
-#### Q8
-### Execute an array of asynchronous functions one after the other in sequence using callbacks
-
-- The asynchronous function can be simulated using setTimeout which executes the callback
-- The array of functions execution can be managed by having a function which takes care of execution of all the async functions
-- Asynchronous functions need not be aware of the function to be executed and will take a callback as argument and execute it after completion
-
-```js
-function asyncFunc1(callback) {
- console.log('Started asyncFunc1');
- setTimeout(() => {
- console.log('Completed asyncFunc1');
- callback();
- }, 3000);
-}
-
-function asyncFunc2(callback) {
- console.log('Started asyncFunc2');
- setTimeout(() => {
- console.log('Completed asyncFunc2');
- callback();
- }, 2000);
-}
-
-function asyncFunc3(callback) {
- console.log('Started asyncFunc3');
- setTimeout(() => {
- console.log('Completed asyncFunc3');
- callback();
- }, 1000);
-}
-
-function callbackManager(asyncFuncs) {
- function nextFuncExecutor() {
- const nextAsyncFunc = asyncFuncs.shift();
- if (nextAsyncFunc && typeof nextAsyncFunc === 'function') {
- nextAsyncFunc(nextFuncExecutor, asyncFuncs);
- }
- }
- nextFuncExecutor();
-}
-
-// driver code
-callbackManager([asyncFunc1, asyncFunc2, asyncFunc3]);
-```
-
-###### Notes
-3 asynchrounous functions are considered here, but the program should work for any number
-
-
-
-#### Q9
-### Execute the given list of asynchronous functions in parallel and return the results as an array to the callback
-```js
-// Example
-function asyncFunc1(callback) {
- setTimeout(() => {
- callback(1);
- }, 3000);
-}
-
-function asyncFunc2(callback) {
- setTimeout(() => {
- callback(2);
- }, 2000);
-}
-
-function asyncFunc3(callback) {
- setTimeout(() => {
- callback(3);
- }, 1000);
-}
-
-asyncParallel([asyncFunc1, asyncFunc2, asyncFunc3], result => {
- console.log(result); // 1, 2, 3 (prints results of each asynchronous function in order)
-});
-```
-
-- The async functions can be executed in parallel using the loop and can be tracked for completion with a counter
-- The callback function can be sent to the async functions and the results will be stored in the array which will be returned after the completion of all
-
-```js
-function asyncParallel(asyncFuncArr, callback) {
- const resultArr = new Array(asyncFuncArr.length);
- let resultCounter = 0;
-
- asyncFuncArr.forEach((async, index) => {
- async(value => {
- resultArr[index] = value;
- resultCounter++;
- if (resultCounter >= asyncFuncArr.length) {
- callback(resultArr);
- }
- });
- });
-}
-```
-
-###### References
-- https://jsvault.com/async-parallel
-
-
-
-#### Q10
-### Write a code to make xmlHTTPRequest to get data from the server asynchronously
-
-- XMLHttpRequest (XHR) objects are used to interact with server to retrieve data from a URL without having to do a full page refresh
-- XHR requests can be initiated by creating the object and providing the arguments such as 'method', url etc
-- The success and failure of the request can be managed by callbacks
-
-```js
-const xhr = new XMLHttpRequest();
-xhr.open("GET", url);
-
-xhr.onload = function() {
- console.log(this.response);
-};
-
-xhr.onerror = function() {
- console.log(this.statusText);
-};
-
-xhr.send();
-```
-
-###### Notes
-XHR is used mainly in AJAX programming
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
-
-
-
-#### Q11
-### Show the working of promise along with resolve & reject code
-
-- The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value
-- Promise returns an object which ramains in pending state until it is resolved or rejected
-- Promise takes a function as an argument called as 'resolver' which can have resolve and reject as parameters
-- Resolve call will resolve the promise and reject will reject the promise (passing data is optional)
-- `then` method on promise object is used to execute the user code after promise settles, which takes functions where 1st one is for success and 2nd for failure
-- Functions with success and failure of the promises are used to illustrate the basics of promise code
-
-```js
-function asyncResolveFunc() {
- function resolver(resolve, reject) {
- resolve('Success');
- }
- return new Promise(resolver);
-}
-
-function asyncRejectFunc() {
- function resolver(resolve, reject) {
- reject('Failure');
- }
- return new Promise(resolver);
-}
-
-// driver code
-const promiseSuccess = asyncResolveFunc();
-const promiseFailure = asyncRejectFunc();
-
-// Succeeded promise .then executes first function passed as argument
-promiseSuccess.then((successData) => { console.log(successData); }, (failureData) => { console.log(failureData); });
-
-// Failed promise .then executes second function passed as argument
-promiseFailure.then((successData) => { console.log(successData); }, (failureData) => { console.log(failureData); });
-```
-
-###### Notes
-Once the promise is resolved or rejected, status will not change
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
-
-
-
-#### Q12
-### Wrap the setTimeout function to convert to a promise
-
-- Promise can be used to wrap the `setTimeout` to make the code more readable
-- Function can take delay as argument and return a promise which gets resolved after timeout is complete
-
-```js
-function setTimeoutPromise(delay) {
- function resolver(resolve) {
- setTimeout(resolve(), delay);
- }
- return new Promise(resolver);
-}
-
-// driver code
-console.log('Task started');
-const timeoutPromise = setTimeoutPromise(3000);
-timeoutPromise.then(() => {
- console.log('Task completed');
-});
-```
-
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
-
-
-
-#### Q13
-### Convert the xmlHTTPRequest to promise based function to get the data from the server asynchronously (fetch)
-
-- The Promise can be used to wrap the XHR request and provide cleaner interface to user for AJAX requests
-- Success and failure of the XHR request can be handled to resolve or reject the promise respectively
-
-```js
-function fetchData(url) {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- xhr.open("GET", url);
-
- xhr.onload = function() {
- try {
- if(this.status === 200 ){
- resolve(this);
- } else{
- reject(this);
- }
- } catch(e){
- reject(e);
- }
- };
-
- xhr.onerror = function() {
- reject(this);
- };
-
- xhr.send();
- });
-}
-
-// driver code
-fetchData("https://reqbin.com/echo/get/json")
-.then(data => {
- console.log(data);
-})
-.catch(err => console.log(err));
-```
-
-###### Notes
-XHR reuqest is no more in use and all the modern browsers use `fetch` API which is based on promise
-
-###### References
-- https://medium.com/@RistaSB/create-ajax-function-with-xmlhttprequest-and-promise-fe7422e38b50
-
-
-
-#### Q14
-### Make a fetch request to retrieve and store JSON data from server
-
-- Fetch API is provided by the browser which returns a promise
-- Fetch takes url as the 1st argument and an object with request details as 2nd optional argument
-- Response is a streamable object and hence we will have to invoke JSON / text method on it which returns promise which settles to the data
-
-```js
-const response = fetch('https://reqbin.com/echo/get/json', {
- method: 'GET', // *GET, POST, PUT, DELETE, etc
- headers: {
- 'Content-Type': 'application/json', // header
- },
-});
-
-// driver code
-response.then(response => {
- const responseData = response.json();
- responseData.then(data => {
- console.log(data);
- });
-})
-.catch(err => {
- console.log(err);
-});
-
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
-
-
-
-#### Q15
-### Cancel a fetch request
-
-- `AbortController` is an interface which can be used to abort a fetch request
-- `signal` object of the AbortController object can be used as the part of the argument to `fetch` and abort on controller object can be used to stop the request
-
-```js
-const controller = new AbortController();
-var signal = controller.signal;
-
-fetch(url, { signal }).then(response => {
- console.log(response);
-}).catch(err => {
- console.warn(err);
-});
-
-controller.abort();
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort
-- https://davidwalsh.name/cancel-fetch
-
-
-
-#### Q16
-### Execute 3 asynchronous functions one after the other in sequence using promise chaining
-
-- The implementation of chaining is that the result is passed through the chain of `then` handlers for all the promises
-- `then` method on Promise also returns a promise which can be used to perform `then` on the returned promise
-- The errors in promise / promise chaining can be handled with the error callback for each promise when it settles or with a generic catch block
-
-```js
-asyncFunc1().then(
- () => {
- console.log('Completed async1');
- asyncFunc2().then(
- () => {
- console.log('Completed async2');
- asyncFunc3().then(
- () => {
- console.log('Completed async3');
- console.log('All succeeded');
- },
- (err) => {
- console.log('Failure in ' + err);
- }
- );
- },
- (err) => {
- console.log('Failure in ' + err);
- }
- );
- },
- (err) => {
- console.log('Failure in ' + err);
- }
-);
-```
-
-```js
-asyncFunc1()
-.then(asyncFunc2)
-.then(asyncFunc3)
-.catch(() => { console.log("Error occured in one of the async function"); });
-```
-
-###### Notes
-If `then` method has a return statement which is a promise then it will be considered for the next promise chain until it settles
-
-###### References
-- https://javascript.info/promise-chaining
-
-
-
-#### Q17
-### Show the working of async await work with promises
-
-- `async` functions are asynchronous functions in which the asynchrous code can be executed in synchronous looking manner using `await`
-- `await` expects a promise and the execution will stop until the promise is resolved
-- If promise gets rejected, error is thrown with failure reason which can be handled using simple try-catch block
-
-```js
-async function asyncAwaitFunc() {
- try {
- console.log('Executes normally when invoked');
- await promiseReturningFunc();
- console.log('Continues the execution after promise resolution');
- } catch (err) {
- console.log('Error occured: ' + err);
- }
-}
-```
-
-###### Notes
-`await` keyword can only be used in a `async` function
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
-- https://javascript.info/async-await
-
-
-
-#### Q18
-### Execute 3 asynchronous functions one after the other in sequence using async await
-
-- Async function with `await` for each promise can be used to execute in sequence
-
-```js
-+async function executor(){
- try{
- await asyncFunc1();
- await asyncFunc2();
- await asyncFunc3();
- console.log('All succeeded');
- }
- catch(){
- console.log("Error occured);
- }
-}();
-```
-
-
-
-#### Q19
-### Execute 3 asynchronous functions one after the other in sequence using promise chaining and do not terminate on failure
-
-- The promise which gets rejected will invoke the 2nd function argument to `then` handler
-- The failure handler will receive the error and continue with next execution which will not propagate failures
-
-```js
-async1()
- .then(
- () => {
- console.log('Async1 success');
- },
- () => {
- console.log('Async1 failure');
- }
- )
- .then(async2)
- .then(
- () => {
- console.log('Async2 success');
- },
- () => {
- console.log('Async2 failure');
- }
- )
- .then(async3)
- .then(
- () => {
- console.log('Async3 success');
- },
- () => {
- console.log('Async3 failure');
- }
- );
-```
-
-
-
-#### Q20
-### Execute 3 asynchronous functions one after the other in sequence using async await and do not terminate on failure
-
-- Unlike promises, `try-catch` block can be used on async functions
-- `catch` block for each asynchronous function can be used to catch errors and continue with next execution which will not propagate failures
-
-```js
-+(async function executor() {
- try {
- await asyncFunc1();
- console.log('Async1 success');
- } catch {
- console.log('Async1 failure');
- }
- try {
- await asyncFunc2();
- console.log('Async2 success');
- } catch {
- console.log('Async2 failure');
- }
- try {
- await asyncFunc3();
- console.log('Async3 success');
- } catch {
- console.log('Async3 failure');
- }
- console.log('All succeeded');
-})();
-```
-
-
-
-#### Q21
-### Execute an array of asynchronous functions which returns a promise, one after the other in sequence
-
-- Asynchronous functions can be executed and promises can be captured in an array
-- Array method `reduce` can be used to make the sequential execution on promise settlement
-
-```js
-const asyncFuncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
-
-asyncFuncArr.reduce((acc, async) => {
- return acc.then(() => async().then(console.log));
-}, Promise.resolve());
-```
-
-```js
-const asyncFuncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
-
-asyncFuncArr.reduce(async (acc, asyncFunc) => {
- await acc;
- console.log(await asyncFunc());
-}, Promise.resolve());
-```
-
-###### Notes
-`Promise.resolve()` is used as the initial value to `reduce`, which resolves the promise immediately,
-
-
-
-#### Q22
-### Execute an array of asynchronous functions simultaneously but print the output in the ordered sequence. Do not wait for printing the data if it already available after promise is settled
-
-- Array method `reduce` can be used to make the simultaneously execution on promise settlement
-- Unlike sequential execution, the parallel execution of asynchronous functions happen but the output will executed in order of sequence
-
-```js
-const asyncFuncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
-
-asyncFuncArr
-.map(async => async())
-.reduce((acc, promise) => {
- return acc.then(() => promise).then(data => console.log(data));
-}, Promise.resolve());
-```
-
-```js
-const asyncFuncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
-
-asyncFuncArr
-.map(async => async())
-.reduce(async (acc, promise) => {
- console.log(await acc.then(() => promise));
-}, Promise.resolve());
-```
-
-
-
-#### Q23
-### Write a code to resolve all the list of asynchronous executions of promises and stop if any of them is rejected. Print the output accordingly
-
-- `Promise.all` is the method which helps to achieve the functionality which settles if all the promises are resolved or any of them are rejected
-- It receives array of promises as an argument to it
-- Array of results will be the success data if all the promises resolves or the error data on failure of the first one
-
-```js
-const asyncArr = [async1, async2, async3];
-const promiseArr = asyncArr.map(async => async());
-
-finalResolution = Promise.all(promiseArr);
-finalResolution.then((output) =>{
- for(let data of output) {
- console.log(data);
- }
-})
-.catch(err =>
- console.log(err)
-);
-```
-
-```js
-const asyncArr = [async1, async2, async3];
-const promiseArr = asyncArr.map(async => async());
-
-(async function () {
- try {
- output = await Promise.all(promiseArr);
- for (let data of output) {
- console.log(data);
- }
- } catch (err) {
- console.log(err);
- }
-})();
-```
-
-###### Notes
-On failure of one of the promise, rest of the pending promises will be cancelled
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
-
-
-
-#### Q24
-### Write a code to resolve all the list of asynchronous executions of promises no matter if each execution succeeds or fails. Print the output of each
-
-- `Promise.allSettled` is the method which helps to achieve the functionality which completes after all promises settle no matter of failures
-- It receives array of promises as an argument to it
-- Array of results will be the output after completion of all promises with status as 'fulfilled' or 'rejected'
-
-```js
-const asyncArr = [async1, async2, async3];
-const promiseArr = asyncArr.map(async => async());
-finalResolution = Promise.allSettled(promiseArr);
-finalResolution
- .then(output => {
- for (let data of output) {
- if (data.status === 'fulfilled') console.log(data.status + ': ' + data.value);
- else if (data.status === 'rejected') console.log(data.status + ': ' + data.reason);
- }
- })
- .catch(err => {
- console.log(err);
- });
-```
-
-```js
-const asyncArr = [async1, async2, async3];
-const promiseArr = asyncArr.map(async => async());
-(async function () {
- try {
- output = await Promise.allSettled(promiseArr);
- for (let data of output) {
- if (data.status === 'fulfilled') console.log(data.status + ': ' + data.value);
- else if (data.status === 'rejected') console.log(data.status + ': ' + data.reason);
- }
- } catch (err) {
- console.log(err);
- }
-})();
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
-- https://davidwalsh.name/promise-allsettled
-
-
-
-#### Q25
-### Explain the working of Promise.race with few asynchronous function example
-
-- The `Promise.race` method returns a promise that fulfills or rejects as soon as one of the promises fulfills or rejects, with the success or failure
-
-```js
-function asyncFunc1() {
- return new Promise(resolve =>
- setTimeout(() => {
- resolve('Resolved async1');
- }, 2000)
- );
-}
-
-function asyncFunc2() {
- return new Promise(resolve =>
- setTimeout(() => {
- resolve('Resolved async2');
- }, 3000)
- );
-}
-
-function asyncFunc3() {
- return new Promise((resolve, reject) =>
- setTimeout(() => {
- reject('Rejected async3');
- }, 1000)
- );
-}
-
-// driver code
-const asyncArr = [asyncFunc1, asyncFunc2, asyncFunc3];
-const promiseArr = asyncArr.map(async => async());
-Promise.race(promiseArr).then(console.log).catch(console.log); // Rejected async3 (catch block)
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race
-
-
-
-#### Q26
-### Design a utility which takes array of asynchronous functions and returns the 1st successful or non successful result with max waiting time set by the user
-
-- `Promise.race` is an in built JavaScript method which helps us to return the first resolved or rejected promise data from promises array
-- Timeout feature can be set by adding a function returning a promise which rejects after specified amount of time
-- If any promise resolves before timeout the promise which settles first will be the output else timeout will cause rejection
-
-```js
-function timeoutFunc() {
- const delay = 500;
- return new Promise((resolve, reject) => {
- setTimeout(() => reject("Timeout"), delay));
- }
-}
-
-const asyncArr = [asyncFunc1, asyncFunc2, asyncFunc3, timeoutFunc];
-const promiseArr = asyncArr.map(asyncFunc => asyncFunc());
-Promise.race(promiseArr).then(console.log).catch(console.log);
-```
-
-
-
-#### Q27
-### Design a utility which takes URL and a value for attempts which will attempt to make a fetch request. If on failure it tries again with increasing delay for number of times which user has requested
-
-- Utility can designed which returns a promise which attempts to make requests and return the data on success
-- The `fetch` request attempts to make calls after increasing time delay on failure
-- If all the attempts by to get response fails, promise gets rejected
-
-```js
-function requestManager(url, attempts = 3) {
- return new Promise(async (resolve, reject) => {
- for (let i = 0; i < attempts; i++) {
- try {
- const response = await fetch(url);
- resolve(response);
- break;
- } catch (err) {
- if (attempts - 1 === i) {
- reject(err);
- break;
- }
- await new Promise(resolve => setTimeout(resolve, 1000 + 1000 * i));
- }
- }
- });
-}
-
-// driver code
-requestManager('https://reqbin.com/echo/get/json', 3).then(
- response => console.log(response),
- error => console.log(error)
-);
-```
-
-###### Notes
-`1000 + 1000 * i` is used for delay after 1st unsuccessful attempt to fetch, which increases the delay on every iteration
-
-###### References
-- https://dev.to/ycmjason/javascript-fetch-retry-upon-failure-3p6g
-
-
-
-#### Q28
-### Show me the working of a generator function
-
-- Generators are functions that can be exited and later re-entered
-- Generator function will have `*` after the keyword `function`
-- Generator when called returns an `iterator` which can be used to call `next` on it
-- `yield` keyword can be used inside such a function and stops the execution
-
-```js
-function* generatorFunc(param){
- const num1 = yield;
- const num2 = yield;
- return num1 + num2;
-}
-
-// driver code
-const it = generatorFunc();
-it.next(); // { value: undefined, done: false}
-it.next(3); // { value: undefined, done: false}
-const sum = it.next(5); // { value: 8, done: true }
-sum.value; // 8
-```
-
-###### Notes
-Data between generator and iterator can be passed in both direction
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
-
-
-
-#### Q29
-### Create a generator to return a random number on every request
-
-- The generation of random number can be implemented in the normal way in the function but will returned and function yields
-- The function will again continue to execute in loop to return a new random number
-
-```js
-function* generatorFunc(param){
- while(true){
- yield Math.ceil(Math.random() * 100);
- }
-}
-
-// driver code
-const it = generatorFunc();
-const rand1 = it.next();
-const rand2 = it.next();
-```
-
-###### Notes
-Genertor function need not complete its execution
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
-
-
-
-#### Q30
-### Write a generator function which uses another generator function internally to fetch the values. Use for..of loop to consume the values
-
-- Generator with the generator can be used to fetch the values using `yield*`
-- The code consuming the parent generator need to be aware of it and can be used directly
-- As the generator return iterator, for..of loop can be used on generator
-
-```js
-function* gen1() {
- yield 1;
- yield* gen2();
- yield 4;
-}
-
-function* gen2() {
- yield 2;
- yield 3;
-}
-
-// driver code
-for (let value of gen1()) {
- console.log(value);
-}
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
-
-
-
-#### Q31
-### Search for the presence of a given value in the nested object using generator
-
-- With the help of generator Inversion of control is possible
-- Instead of function seaching for the key by passing the callback or key, the logic can be implemented in the controlling code
-- For..of loop calling the recursive generator function on object can be used to achieve this
-
-```js
-function* objectReader(obj){
- for(let key in obj){
- if(typeof obj[key] === "object"){
- yield *objectReader(obj[key]);
- }
- else{
- yield obj[key];
- }
- }
-}
-
-// driver code
-const it = objectReader({a: 1, b: 2, c: 3, d: { x: 4, y: 5, z: {m: 6, b: 7}}});
-const searchValue = 5;
-
-for(let value of it){
- if(value === searchValue) {
- console.log(searchValue + " exists");
- }
-}
-```
-
-
-
-#### Q32
-### Write an interface to mock Promise in JavaScript which can be called to create a promise with resolve and reject. Also implement then functionality
-
-- Basic promise interface will allow creation of promise by passing resolver as the argument
-- `resolve` and `reject` methods will have to be passed to the resolver which the user code will ivoke with data once settled
-- `setTimeout` with zero delay can be used to not immediately execute the resolver
-- List of callbacks to `then` to be invoked can be stores in the array of success and failure list
-- Once resolved or rejected, promise cannot change the state
-
-```js
-function MyPromise(resolver) {
- let successList = [];
- let failureList = [];
- let resolution = 'pending';
- let data;
-
- function resolve(value) {
- if (resolution === 'pending') {
- for (let successCb of successList) {
- successCb(value);
- }
- resolution = 'resolved';
- data = value;
- }
- }
-
- function reject(value) {
- if (resolution === 'pending') {
- for (let failureCb of failureList) {
- failureCb(value);
- }
- resolution = 'rejected';
- data = value;
- }
- }
-
- setTimeout(() => {
- try {
- resolver(resolve, reject);
- } catch (err) {
- reject(err);
- }
- }, 0);
-
- return {
- status: resolution,
- then: function (onSuccess, onFailure) {
- if (resolution === 'pending') {
- successList.push(onSuccess);
- failureList.push(onFailure);
- } else {
- resolution === 'resolved' ? onSuccess(data) : onFailure(data);
- }
- },
- };
-}
-
-// driver code
-let p = new MyPromise((resolve, reject) => {
- resolve(10);
-});
-
-p.then(data => console.log(data), console.log);
-```
-
-###### Notes
-ES6 Promise is much more complex and sophesticated than the above shown implementation.
-
-
-
-#### Q33
-### Write a function which helps to achieve the `Promise.all` functionality using promises
-
-- `Promise.all` method is fail fast procedure to return all the promise resolved data in array or failed reason
-
-```js
-function PromiseAll(promiseArr) {
- return new Promise((resolve, reject) => {
- const dataArr = new Array(promiseArr.length);
- let resolution = 'pending';
-
- for (let index in promiseArr) {
- promiseArr[index].then(
- data => {
- if (resolution === 'pending') {
- dataArr[index] = {
- value: data,
- status: 'fulfilled',
- };
- if (!dataArr.includes(undefined)) {
- resolution = 'fulfilled';
-
- resolve(dataArr);
- }
- }
- },
- err => {
- if (resolution === 'pending') {
- resolution = 'rejected';
- reject({
- reason: err,
- status: 'rejected',
- });
- }
- }
- );
- }
- });
-}
-
-// driver code
-PromiseAll([
- new Promise(resolve => setTimeout(resolve, 1000)),
- new Promise((resolve, reject) => setTimeout(reject, 2000)),
-]).then(console.log, console.log);
-```
-
-
-
-#### Q34
-### Show the working generator function with promises
-
-- Generator can be used with promises where yield will return a promise and promise resolution can trigger continuation
-- Helper function is used to manage this flow which takes generator function as an argument and executes it
-
-```js
-// asynchronous helper function returning a promise which gets resolved after the specified delay with data
-function asyncFunc(data, delay){
- return new Promise(resolve => setTimeout(resolve, delay, data));
-}
-
-function* gen() {
- // async function calls to yield promise
- const num1 = yield asyncFunc(2, 1000);
- const num2 = yield asyncFunc(1, 2000);
- console.log(num1 + num2); // 3 (2 + 1)
-}
-
-function executeGeneratorWithPromise(gen) {
- const it = gen();
-
- // takes input as promise from generator
- function handle(promise) {
- if (!promise.done)
- promise.value
- .then(data => {
- // continue the execution of generator after promise is resolved
- handle(it.next(data));
- })
- .catch(err => iterator.throw(err));
- }
-
- handle(it.next());
-}
-
-// call generator executor function and pass generator function reference
-executeGeneratorWithPromise(gen);
-```
-
-###### Notes
-The generator and the helper function 'executeGeneratorWithPromise' executes hand in hand, where the generator pauses returning a promise and the helper function starts generator on that promise resolution
-
-###### References
-- https://www.promisejs.org/generators/
-
-
-
-[[↑] Back to top](#home)
diff --git a/challenges/collections-challenges.md b/challenges/collections-challenges.md
new file mode 100644
index 0000000..a1055bf
--- /dev/null
+++ b/challenges/collections-challenges.md
@@ -0,0 +1,547 @@
+
+
+## JavaScript interview code challenges on Collections - challenges
+
+1. [Write a function which can concatenate 2 arrays. If only one array is passed it will duplicate it](#Q1)
+1. [Write a program to replace 3 center elements of the 1st array by center 3 elements of the 2nd array](#Q2)
+1. [Sort the given array of integers in ascending or descending order](#Q3)
+1. [Sort the given array of objects in ascending order according the authors lastname](#Q4)
+1. [Square all the positive numbers of the array and return the output array](#Q5)
+1. [Write a code to generate an array with range of numbers and shuffle them](#Q6)
+1. [Check if the user with the name "John" exists in the array of objects](#Q7)
+1. [Generate an array of objects with properties id and full name from an array of objects where each object will have id, firstname and lastname](#Q8)
+1. [Write a program to calculate the sum of all the values of an array](#Q9)
+1. [Get the maximum value from a numbers array along with its index](#Q10)
+1. [Find the number of occurences of minimum value in the numbers list](#Q11)
+1. [Create an array of length n with all the values of it set to 10](#Q12)
+1. [Write the code to remove the duplicates from the array](#Q13)
+1. [Design a flat function which flattens an array to any depth](#Q14)
+1. [Check if all the students of have passed or not (40 is the pass marks)](#Q15)
+1. [Get the average of all the salaries which is greater than 10000 from the department of "IT" from the array of objects)](#Q16)
+1. [Extract the list of all the elements from the list of numbers given in 2 arrays](#Q17)
+1. [Get the list of all distinct elements which are present in both list of numbers](#Q18)
+1. [Extract list of elements present only in the first list given.](#Q19)
+1. [Create a function named "average" which can calculate the average of an array and should be available to be called from any Array object.](#Q20)
+1. [Write a code to eliminate duplicate objects in an array where each object has an 'id' property which can be used to identify the object and the duplicate object with lower rank to be removed](#Q21)
+1. [Create an array which will only accept string values. (Homogeneous array of strings)](#Q22)
+1. [Create a Proxy object through which the array can be accessed as usual but also allow to access the values through negative indices](#Q23)
+
+---
+
+#### Q1
+### Write a function which can concatenate 2 arrays. If only one array is passed it will duplicate it
+
+- Function can take 2 arguments which concatenates arrays
+- 2nd array parameter can be defaulted to 1st array if the value is not passed
+
+```js
+function mergeArray(arr1, arr2 = arr1){
+ return [...arr1, ...arr2];
+}
+```
+
+```js
+function mergeArray(arr1, arr2 = arr1){
+ return arr1.concat(...arr2);
+}
+```
+
+```js
+function mergeArray(arr1, arr2 = arr1){
+ arr1.push(...arr2);
+ return arr1;
+}
+```
+
+###### Notes
+When 2nd argument is not passed, the case is same as duplicating the array
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
+
+
+
+#### Q2
+### Write a program to replace 3 center elements of the 1st array by center 3 elements of the 2nd array
+
+- `slice` method on array can be used to fetch the values of range in the array
+- `splice` method on array can be used to replace the value of range in the array
+
+```js
+const a = [1, 2, 3, 4, 5];
+const b = [4, 0, 0, 0, 8];
+
+const startPositionFor1stArray = a.length / 2 - 1;
+const startPositionFor2ndArray = b.length / 2 - 1;
+a.splice(startPositionFor1stArray, 3, ...b.slice(startPositionFor2ndArray, startPositionFor2ndArray + 3));
+```
+
+###### Notes
+The center most 3 values of array 'a' is replaced by 'b'
+
+
+
+#### Q3
+### Sort the given array of integers in ascending or descending order
+
+- `sort` method sorts the elements of an array in place and returns the sorted array
+- It receives a function as an argument, which is used for comparision
+
+```js
+arr.sort((a, b)=> a - b); // ascending
+arr.sort((a, b)=> b - a); // descending
+```
+
+###### Notes
+If function is not passed an argument, default sorting will happen
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
+
+
+
+#### Q4
+### Sort the given array of objects in ascending order according the authors lastname
+```js
+// Example
+const books = [
+ { name: "Harry Potter", author: "Joanne Rowling" },
+ { name: "Warcross", author: "Marie Lu" },
+ { name: "The Hunger Games", author: "Suzanne Collins" },
+]
+```
+- `sort` takes a function and expects the return value to be an integer for sorting
+- The last names of the author can be compared and the result can be returned for sorting
+
+```js
+books.sort((book1, book2) => {
+ const authorLastName1 = book1.author.split(" ")[1];
+ const authorLastName2 = book2.author.split(" ")[1];
+ return authorLastName2 > authorLastName1 ? -1 : 1;
+});
+```
+
+###### Notes
+Returning a true or false will not work as the algorithm expects an integer value
+
+
+
+#### Q5
+### Square all the positive numbers of the array and return the output array
+
+- `filter` is the method on Array which can be used to filter. It receives a function which can return boolean to filter the elements
+- `map` is the method on Array which can be used to map the values to new values. It receives a function which can return the modified value
+
+```js
+const positiveArr = arr.filter((value) => value >= 0);
+const squaredPositiveArr = arr.map((value) => value * value);
+```
+
+```js
+const squaredPositiveArr = arr.filter((value) => value >= 0).map((value) => value * value);
+```
+
+###### Notes
+2nd solution uses method chaining where the return value from `filter` fuction is an array on which `map` method is being called
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
+
+
+
+#### Q6
+### Write a code to generate an array with range of numbers and shuffle them
+
+- An array of numbers in the range can be generated from a function which can take start and end value of the range
+- The shuffling can be achieved simply by sorting the array using a function which randomly returns positive or negative numbers
+- The shuffling of the values can be also done by picking a value from a random index from the current array and moving it in to a new array
+
+```js
+function rangeGenFunc(start = 1, end = 0) {
+ const arr = [];
+ for (let i = start; i <= end; i++) {
+ arr.push(i);
+ }
+ return arr;
+}
+
+const arr = rangeGenFunc(1, 10); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+arr.sort(() => 0.5 - Math.random()); // [6, 8, 5, 10, 4, 3, 9, 2, 7, 1]
+```
+
+```js
+function* rangeGen(start = 1, end = 0) {
+ for (let i = start; i <= end; i++){
+ yield i;
+ }
+}
+
+let arr = [...rangeGen(1, 10)]; // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+let shuffledArr = [];
+const length = arr.length;
+for (let i = 0; i < length; i++) {
+ shuffledArr.push(...arr.splice(Math.floor(Math.random() * arr.length), 1));
+}
+
+console.log(shuffledArr) // [5, 4, 7, 10, 3, 6, 8, 2, 1, 9]
+```
+
+###### Notes
+2nd solution uses generator function to generate the range of values which can be converted to an array by spreading.
+
+
+
+#### Q7
+### Check if the user with the name "John" exists in the array of objects
+
+```js
+const doesJohnExist = arr.some((obj) => obj.name === "John");
+```
+
+```js
+const jonhObject = arr.find((obj) => obj.name === "John");
+const doesJohnExist = jonhObject ? true : false;
+```
+
+```js
+const jonhIndex = arr.findIndex((obj) => obj.name === "John");
+const doesJohnExist = jonhIndex < 0 ? false : true;
+```
+
+
+
+#### Q8
+### Generate an array of objects with properties id and full name from an array of objects where each object will have id, firstname and lastname
+
+- To manipulate array of objects `map` method can be used
+
+```js
+const employeesListWithFullName = arr.map((obj) => { return { id, fullName: obj.firstName + " " + obj.lastName } });
+```
+
+
+
+#### Q9
+### Write a program to calculate the sum of all the values of an array
+
+- Sum of the values of an array can calculated by iterating and adding all the values of the array
+- `reduce` method of array can be used efficiently to calculate the sum with or without initial value
+
+```js
+const sum = arr.reduce((acc, value) => acc + value, 0);
+```
+
+```js
+const sum = arr.reduce((acc, value) => acc + value);
+```
+
+```js
+const sum = 0;
+for(let value of arr){
+ sum = sum + value;
+}
+```
+
+###### Notes
+`reduce` method takes a function as 1st argument and initial value as 2nd argument. The return value of current iteration will be 1st argument for the next iteration along with the next element of the array
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
+
+
+
+#### Q10
+### Get the maximum value from a numbers array along with its index
+
+- `Math.max` is a method which returns maximum value from a given list of values
+- `reduce` can also be designed to return the maximum value of each comparision
+
+```js
+const max = Math.max(...arr);
+arr.indexOf(max); // position of max number
+```
+
+```js
+let max = a[0], position = 0;
+for(let index in arr){
+ if(arr[index] > max){
+ position = index
+ max = value;
+ }
+}
+
+position; // position of max number
+```
+
+```js
+const max = arr.reduce((a, b) => a < b ? a : b);
+arr.indexOf(max); // position of max number
+```
+
+###### Notes
+Though 2nd solution is verbose compared but has good performance
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min
+
+
+
+#### Q11
+### Find the number of occurences of minimum value in the numbers list
+
+- `filter` method can be used to fetch all the minimum values and we can get the count of those valuses
+
+```js
+const min = Math.min(...arr);
+minArr = arr.filter((value) => value === min);
+minArr.length; // count of minimum value occurences
+```
+
+
+
+#### Q12
+### Create an array of length n with all the values of it set to 10
+
+- `fill` is a method on Array prototype which fills all the slots of array with the value given passed as the argument
+
+```js
+const n = 5;
+const arr = new Array(n);
+arr.fill(10);
+```
+
+###### Notes
+If an object is passed the object reference is copied to all the slots and not the different objects
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill
+
+
+
+#### Q13
+### Write the code to remove the duplicates from the array
+
+- Set is a data structure which does not allow duplicate elements
+
+```js
+const set = new Set(...arr);
+const distinctArr = [...set];
+```
+
+
+
+#### Q14
+### Design a flat function which flattens an array to any depth
+
+- Flat function can be used to flatten the array by recursive call
+
+```js
+function flat(arr){
+ const flatArr = [];
+ arr.forEach((value) => {
+ if(Array.isArray(value)){
+ flat(value);
+ }
+ else{
+ flatArr.push(value);
+ }
+ });
+ return flatArr;
+}
+```
+
+
+
+#### Q15
+### Check if all the students of have passed or not (40 is the pass marks)
+
+- `every` is a method on Array prototype which returns true only if all the elements condition satisfies the condition
+
+```js
+const isAllPass = students.every((student) => student.marks >= 40);
+```
+
+
+
+#### Q16
+### Get the average of all the salaries which is greater than 10000 from the department of "IT" from the array of objects)
+
+```js
+const itEmployeesWithSalaryGT10K = employees.filter((employee) => employee.salary > 10000 && employee.dept === 'IT );
+const itTotalSalaryGT10K = itEmployeesWithSalaryGT10K.reduce((acc, value) => acc + value, 0);
+const itAvgSalaryGT10K = itTotalSalaryGT10K / itEmployeesWithSalaryGT10K.length;
+```
+
+
+
+#### Q17
+### Extract the list of all the elements from the list of numbers given in 2 arrays
+
+- The union array will be the result if all the elements from the 2 arrays are picked
+
+```js
+const set1 = new Set(...arr1);
+const set2 = new Set(...arr2);
+const distinctArr = [...set1, ...set2];
+```
+
+
+
+#### Q18
+### Get the list of all distinct elements which are present in both list of numbers
+
+- The intersection array will be the result if the common elements from the 2 arrays are picked
+
+```js
+const intersectionArr = arr1.filter(value => arr2.includes(value));
+const distinctIntersectionArr = [...new Set(intersectionArr)];
+```
+
+```js
+const set1 = new Set(arr1);
+const set2 = new Set(arr2);
+const distinctIntersectionArr = [...set1].filter(value => set2.has(value));
+```
+
+
+
+#### Q19
+### Extract list of elements present only in the first list given.
+
+- The only present elements of 1st list will be the result when all the elements of 1st list not present in the 2nd are chosen
+
+```js
+const set1 = new Set(arr1);
+const set2 = new Set(arr2);
+const intersectionArr = [...set1].filter(value => !set2.has(value));
+```
+
+###### Notes
+Elements of 2nd list only can be obtained by checking for all the elements of lis 2 which are not present in list1
+
+
+
+#### Q20
+### Create a function named "average" which can calculate the average of an array and should be available to be called from any Array object.
+
+- The function added to Array prototype are accessible to all the objects of Array
+
+```js
+Array.prototype.average = function (){
+ let total = 0;
+
+ for(let index in this) {
+ total += this[index];
+ }
+ return total / this.length;
+}
+```
+
+
+
+#### Q21
+### Write a code to eliminate duplicate objects in an array where each object has an 'id' property which can be used to identify the object and the duplicate object with lower rank to be removed
+```js
+// Example
+const arr = [
+ {
+ id: 1,
+ name: 'emp1',
+ rank: 4,
+ },
+ {
+ id: 2,
+ name: 'emp2',
+ rank: 1,
+ },
+ {
+ id: 2,
+ name: 'emp2',
+ rank: 2, // this is a duplicate object (id = 2) and has lower rank
+ },
+ {
+ id: 3,
+ name: 'emp3',
+ rank: 3,
+ },
+];
+```
+
+- The duplicate objects cannot be removed using `Set` as the 2 objects with same structure and data have different references
+- `Map` can be used to have 'id' as the key and object as value
+- If 'id' is already present in the array, object with the higher rank can be retained
+
+```js
+const map = new Map();
+
+arr.forEach(obj => {
+ if (map.has(obj.id)) {
+ if (obj.rank > map.get(obj.id)) {
+ map.set(obj.id, obj);
+ }
+ } else {
+ map.set(obj.id, obj);
+ }
+});
+
+distinctArr = [...map.values()];
+```
+
+
+
+#### Q22
+### Create an array which will only accept string values. (Homogeneous array of strings)
+
+- Array in JavaScript a collection of values of any type by default
+- Proxy can be used to validate and insert to the array only if the value satisfies the condition using `set` trap
+
+```js
+var stringsArr = [];
+
+var stringsArr = new Proxy(stringsArr, {
+ set(target, prop, receiver){
+ if(typeof receiver === "string"){
+ target[target.length] = receiver;
+ }
+ return true;
+ }
+});
+
+// driver code
+stringsArr.push("Hello", 5, {}, "world", true, [1, 2, 3]);
+stringsArr; // ["Hello", "world"]
+```
+
+###### Notes
+The functionality of the code can be modified to make the array accept any one or more kind of values only
+
+
+
+#### Q23
+### Create a Proxy object through which the array can be accessed as usual but also allow to access the values through negative indices
+```js
+// Example
+let arr = [10, 20, 30];
+
+arr[-1]; // 30
+arr[-2]; // 20
+```
+
+- `get` trap of proxy can be used to map the negative index to the valid array position
+
+```js
+arr = new Proxy(arr, {
+ get(target, handler) {
+ if (handler < 0) return target[target.length + Number(handler)];
+ else return target[handler];
+ },
+});
+```
+
+
+
+[[↑] Back to top](#home)
diff --git a/challenges/collections-concepts.md b/challenges/collections-concepts.md
new file mode 100644
index 0000000..d6187ea
--- /dev/null
+++ b/challenges/collections-concepts.md
@@ -0,0 +1,522 @@
+
+
+## JavaScript interview code challenges on Collections - concepts
+
+1. [Show the different ways of creating an array](#Q1)
+1. [Write a program to iterate over an array and print all the values of it](#Q2)
+1. [Write a program to append and prepend, single or multiple values in to an array](#Q3)
+1. [Show how insertion and removal of elements can happen in the array for given index](#Q4)
+1. [Show the different ways of emptying an array which has values](#Q5)
+1. [Check if given input is an array or not](#Q6)
+1. [Show how an array in JavaScript can act like a stack and queue](#Q7)
+1. [Create an array by removing all the holes of the array](#Q8)
+1. [Optimize the given statements having lot of logical checks to use a compact and cleaner logic](#Q9)
+1. [Write a program to iterate over a 2 dimensional array and print all the values of it](#Q10)
+1. [Write a program to store values in to a set](#Q11)
+1. [Write a program to store values in to a map](#Q12)
+1. [Write a code to iterate over a set](#Q13)
+1. [Write a code to iterate over a map](#Q14)
+1. [Show how map is different from object to store key value pairs with coding example](#Q15)
+1. [Write a program to polyfill `filter` functionality of the Array](#Q16)
+1. [Write a program to polyfill `map` functionality of the Array](#Q17)
+1. [Write a program to polyfill `reduce` functionality of the Array](#Q18)
+
+---
+
+#### Q1
+### Show the different ways of creating an array
+
+- Arrays are the collection of values in javascript. Array is a special type of object in JavaScript
+- Arrays values are indexed from 0 and have special property length which stores the count of elements present in array
+
+```js
+// literal form
+const arr = [];
+```
+
+```js
+// consturctor form
+const arr = new Array();
+```
+
+```js
+// pre defined number of slots
+const arr = new Array(10);
+```
+
+```js
+// with values
+const arr = [1, true, "string"];
+```
+
+```js
+// constructor form with values
+const arr = new Array(1, true, "string");
+```
+
+###### References
+- https://javascript.info/array
+
+
+
+#### Q2
+### Write a program to iterate over an array and print all the values of it
+
+- Arrays can be iterated by using its index to fetch the values
+- Arrays also can be iterated with for each style loops
+
+```js
+for(let i =0; i < arr.length; i++){
+ console.log(arr[i]);
+}
+```
+
+```js
+for(let index in arr){
+ console.log(arr[index]);
+}
+```
+
+```js
+for(let value of arr){
+ console.log(value);
+}
+```
+
+```js
+arr.forEach(val => console.log(val));
+```
+
+
+
+#### Q3
+### Write a program to append and prepend, single or multiple values in to an array
+
+- Values to the array can be appended using `push` method of array
+- Values to the array can be prepended using `unshift` method of array
+
+```js
+const arr = [2, 3];
+arr.push(4); // [2, 3, 4]
+arr.unshift(1); // [1, 2, 3, 4]
+```
+
+```js
+const arr = [3, 4];
+arr.push(5, 6); // [3, 4, 5, 6]
+arr.unshift(1, 2); // [1, 2, 3, 4, 5, 6]
+```
+
+```js
+const arr = [1, 2, 3];
+const otherArr = [4, 5, 6];
+arr.push(...otherArr); // [1, 2, 3, 4, 5, 6]
+arr.unshift(...arr); // [4, 5, 6, 1, 2, 3, 4, 5, 6]
+```
+
+###### Notes
+To remove the elements from the end of the array `pop` operation can be used but one element at a time. To remove the elements from the start of the array `shift` operation can be used but one element at a time
+
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift
+
+
+
+#### Q4
+### Show insertion and removal of elements can happen in the array for given index
+
+- Values of the array can be removed from any position using `splice` method of array
+- Values of the array can also be inserted to any position using `splice` method of array
+- 2nd argument is passed as 0 which inserts the elements without replacing
+- The values passed after 2nd argument are considered for insertion
+
+```js
+const arr = [1, 2, 2, 3];
+const position = 2;
+const count = 1;
+arr.splice(position, count); // [2]
+console.log(arr); // [1, 2, 3]
+```
+
+```js
+const arr = [1, 2, 4, 5];
+const position = 2;
+arr.splice(position, 0, 3);
+console.log(arr); // [1, 2, 3, 4, 5]
+```
+
+###### Notes
+'count' indicates the number of elements to be removed from the index 'position'. Multiple values can be inserted or removed using `splice`
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
+
+
+
+#### Q5
+### Show the different ways of emptying an array which has values
+
+- Array can be emptied by giving a new reference of an empty array
+- Setting the `length` of the array to 0 will automatically makes the array empty
+- `pop` operation on array can also be used to empty the array where each elements get removed
+
+```js
+arr = [];
+```
+
+```js
+arr.length = 0;
+```
+
+```js
+while(arr.length > 0){
+ arr.pop();
+}
+```
+
+```js
+arr.splice(0, arr.length)
+```
+
+###### Notes
+`splice` operation used here to empty the array is a trick by passing the length of the array as argument, where all the elements of the array get removed
+
+###### References
+- https://www.javascripttutorial.net/array/4-ways-empty-javascript-array/
+
+
+
+#### Q6
+### Check if given input is an array or not
+
+- `Array.isArray` is a method which checks if the given argument is an array or not
+- Alternatively the `toString` method present on Object prototype can be used to check if it is an array
+
+```js
+Array.isArray(arr);
+```
+
+```js
+Object.prototype.toString.call(arr) === '[object Array]'
+```
+
+###### Notes
+`typeof` operator cannot be used to check if a value is an array or not because array is an object and `typeof arr` returns us "object"
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
+
+
+
+#### Q9
+### Show how an array in JavaScript can act like a stack and queue
+
+- Stack is a 'Last In First Out' data structure can be achieved using `push` and `pop` operations
+- Queue is a 'First In First Out' data structure can be achieved using `push` and `shift` operations
+
+```js
+// To add the value to the stack
+arr.push(value);
+
+// To remove the value from the stack
+arr.pop();
+```
+
+```js
+// To add the value to the queue
+arr.push(value);
+
+// To remove the value from the queue
+arr.shift();
+```
+
+
+
+#### Q16
+### Create an array by removing all the holes of the array
+
+- Holes are `undefined` value present inside array
+- Holes do not get iterated in `filter` which will just fetch all the values except `undefined`
+
+```js
+const uniqueArr = arr.filter(value => true);
+```
+
+###### Notes
+Holes can be formed when an array value by index is deleted. Example: `delete arr[index]`
+
+
+
+#### Q21
+### Optimize the given statements having lot of logical checks to use a compact and cleaner logic
+```js
+// Example1
+browser === "chrome" || browser === "firefox" || browser === "IE" || browser === "safari"
+
+// Example2
+browser !== "chrome" && browser !== "firefox" && browser !== "IE" && browser !== "safari"
+```
+
+- Examples can be modified to store the values of comparision in an array and check for the presence of value if it is present inside array
+
+```js
+// Example1
+// browser === "chrome" || browser === "firefox" || browser === "IE" || browser === "safari"
+
+const browserList = ["chrome", "firefox", "IE", "safari"];
+browserList.includes(browser);
+```
+
+```js
+// Example2
+// browser !== "chrome" && browser !== "firefox" && browser !== "IE" && browser !== "safari"
+
+const browserList = ["chrome", "firefox", "IE", "safari"];
+!browserList.includes(browser);
+```
+
+###### Notes
+Generally this use case can be implemented for `if` conditions
+
+
+
+#### Q22
+### Write a program to iterate over a 2 dimensional array and print all the values of it
+
+- Arrays can be iterated by using its index to fetch the values
+- Arrays also can be iterated with for each style loops, with one loop to iterate the rows and inside it for cells
+
+```js
+for (let i = 0; i < arr.length; i++) {
+ for (let j = 0; j < arr[i].length; j++) {
+ console.log(arr[i][j]);
+ }
+}
+```
+
+```js
+for (let i = 0; i < arr.length; i++) {
+ for (let j = 0; j < arr[i].length; j++) {
+ console.log(arr[i][j]);
+ }
+}
+```
+
+```js
+for (let rowArr of arr) {
+ for (let value of rowArr) {
+ console.log(value);
+ }
+}
+```
+
+```js
+arr.forEach(rowArr => rowArr.forEach(val => console.log(val)));
+```
+
+
+
+#### Q23
+### Write a program to store values in to a set
+
+- Set lets us store unique values of any type
+- Set can be created empty & then added with values or can be initialized also
+
+```js
+const set = new Set();
+set.add(1);
+set.add(true);
+set.add("text");
+set.add(1);
+
+set; // 1, true, "text"
+```
+
+```js
+const set = new Set([1, 2, 3]);
+
+set; // 1, 2, 3
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
+
+
+
+#### Q24
+### Write a program to store values in to a map
+
+- `Map` holds key-value pairs and remembers the original insertion order of the keys
+- `Map` can be created empty & then added with values or can be initialized also with key-value pairs
+
+```js
+const map = new Map();
+map.set(1, 1000);
+map.set(true, false);
+map.set("text", "String");
+
+map; // [1, 1000] [true, false] ["text", "String"]
+```
+
+```js
+const map = new Map([[1, "One"], [2, "two"], [3, "three"]]);
+map; // [1, "One"] [2, "two"] [3, "three"]
+```
+
+###### Notes
+Unlike objects, `Map` can have any primitive or object as the key
+
+###### References
+
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
+
+
+
+#### Q25
+### Write a code to iterate over a set
+
+- `set` is an iterable object and can be iterated using for..of loop
+- `set` can also be iterated by simple `forEach` loop
+
+```js
+for(let val of set) console.log(val);
+```
+
+```js
+set.forEach(value => console.log(value));
+```
+
+
+
+#### Q26
+### Write a code to iterate over a map
+
+- `map` is an iterable object and can be iterated using for..of loop
+- `map` can also be iterated by simple `forEach` loop
+
+```js
+for(let val of map) console.log(val[0], val[1]);
+```
+
+```js
+for(let key of map.keys()) console.log(key, map.get(key));
+```
+
+```js
+map.forEach((value, key) => console.log(key, value));
+```
+
+
+
+#### Q27
+### Show how map is different from object to store key value pairs with coding example
+
+- Map does not contain any keys by default unlike objects which has keys from its prototype
+- Map's keys can be any value (including functions, objects, or any primitive) unlike object where keys are only strings
+- The keys in Map are ordered in a simple, straightforward way
+- The number of items in a Map is easily retrieved from its `size` property
+- Map is an iterable object
+
+```js
+map.set(1, 'Mapped to a number'); // primitive number as key
+map.set('1', 'Mapped to a string'); // string value as key
+map.set({}, 'Mapped to a object'); // object as key
+map.set([], 'Mapped to an array'); // array as key
+map.set(()=>{}, 'Mapped to a function'); // function as key
+```
+
+###### Notes
+Maps perform better than objects in most of the scenarios involving addition and removal of keys
+
+
+
+#### Q36
+### Write a program to polyfill `filter` functionality of the Array
+
+- `filter` iterates over the all values of array and passes value, index and array (itself) as the arguments
+- Function returns a new array which filtering the values of the original array
+
+```js
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function(callback) {
+
+ if(typeof callback !== "function")
+ throw new Error("Argument passed has to be a function");
+
+ let newArray = [];
+
+ for(let index in this) {
+ if(callback(this[index], index, this)){
+ newArray.push(this[index]);
+ }
+ }
+ return newArray;
+ }
+}
+```
+
+###### Notes
+The solution is a simple polyfill of `filter` and not intended to handle all the corner scenarios
+
+
+
+#### Q37
+### Write a program to polyfill `map` functionality of the Array
+
+- `map` iterates over the all values of array and passes value, index and array (itself) as the arguments
+- Function returns a new array which is same as the length of the original array
+
+```js
+if (!Array.prototype.map) {
+ Array.prototype.map = function(callback) {
+ if(typeof callbak !== "function")
+ throw new Error("Argument passed has to be a function");
+
+ let newArray = [];
+
+ for(let index in this) {
+ newArray.push(callback(this[index], index, this));
+ }
+ return newArray;
+ }
+}
+```
+
+###### Notes
+The solution is a simple polyfill of `map` and not intended to handle all the corner scenarios
+
+
+
+#### Q38
+### Write a program to polyfill `reduce` functionality of the Array
+
+- `reduce` iterates over the all values of array and passes value, index and array (itself) as the arguments
+- `reduce` accepts an optional initial value which when not provided can be skipped
+- Function returns a single value after all the iteration
+
+```js
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(callback, init) {
+ let startPosition = 0;
+ let accumulator = init ?? this[startPosition++];
+
+ for(let index = startPosition; index < this.length; index++) {
+ accumulator = callback(accumulator, this[index], index, this);
+ }
+ return accumulator;
+ }
+}
+```
+
+###### Notes
+The solution is a simple polyfill of `reduce` and not intended to handle all the corner scenarios
+
+
+
+[[↑] Back to top](#home)
diff --git a/challenges/collections.md b/challenges/collections.md
deleted file mode 100644
index 093d54f..0000000
--- a/challenges/collections.md
+++ /dev/null
@@ -1,1059 +0,0 @@
-
-
-## JavaScript interview code challenges on Collections
-
-1. [Show the different ways of creating an array](#Q1)
-2. [Write a program to iterate over an array and print all the values of it](#Q2)
-3. [Write a program to append and prepend, single or multiple values in to an array](#Q3)
-4. [Show how insertion and removal of elements can happen in the array for given index](#Q4)
-5. [Show the different ways of emptying an array which has values](#Q5)
-6. [Check if given input is an array or not](#Q6)
-7. [Write a function which can concatenate 2 arrays. If only one array is passed it will duplicate it](#Q7)
-8. [Write a program to replace 3 center elements of the 1st array by center 3 elements of the 2nd array](#Q8)
-9. [Show how an array in JavaScript can act like a stack and queue](#Q9)
-10. [Sort the given array of integers in ascending or descending order](#Q10)
-11. [Sort the given array of objects in ascending order according the authors lastname](#Q11)
-12. [Square all the positive numbers of the array and return the output array](#Q12)
-13. [Write a code to generate an array with range of numbers and shuffle them](#Q13)
-14. [Check if the user with the name "John" exists in the array of objects](#Q14)
-15. [Generate an array of objects with properties id and full name from an array of objects where each object will have id, firstname and lastname](#Q15)
-16. [Create an array by removing all the holes of the array](#Q16)
-17. [Write a program to calculate the sum of all the values of an array](#Q17)
-18. [Get the maximum value from a numbers array along with its index](#Q18)
-19. [Find the number of occurences of minimum value in the numbers list](#Q19)
-20. [Create an array of length n with all the values of it set to 10](#Q20)
-21. [Optimize the given statements having lot of logical checks to use a compact and cleaner logic](#Q21)
-22. [Write a program to iterate over a 2 dimensional array and print all the values of it](#Q22)
-23. [Write a program to store values in to a set](#Q23)
-24. [Write a program to store values in to a map](#Q24)
-25. [Write a code to iterate over a set](#Q25)
-26. [Write a code to iterate over a map](#Q26)
-27. [Show how map is different from object to store key value pairs with coding example](#Q27)
-28. [Write the code to remove the duplicates from the array](#Q28)
-29. [Design a flat function which flattens an array to any depth](#Q29)
-30. [Check if all the students of have passed or not (40 is the pass marks)](#Q30)
-31. [Get the average of all the salaries which is greater than 10000 from the department of "IT" from the array of objects)](#Q31)
-32. [Extract the list of all the elements from the list of numbers given in 2 arrays](#Q32)
-33. [Get the list of all distinct elements which are present in both list of numbers](#Q33)
-34. [Extract list of elements present only in the first list given.](#Q34)
-35. [Create a function named "average" which can calculate the average of an array and should be available to be called from any Array object.](#Q35)
-36. [Write a program to polyfill `filter` functionality of the Array](#Q36)
-37. [Write a program to polyfill `map` functionality of the Array](#Q37)
-38. [Write a program to polyfill `reduce` functionality of the Array](#Q38)
-39. [Write a code to eliminate duplicate objects in an array where each object has an 'id' property which can be used to identify the object and the duplicate object with lower rank to be removed](#Q39)
-40. [Create an array which will only accept string values. (Homogeneous array of strings)](#Q40)
-41. [Create a Proxy object through which the array can be accessed as usual but also allow to access the values through negative indices](#Q41)
-
----
-
-#### Q1
-### Show the different ways of creating an array
-
-- Arrays are the collection of values in javascript. Array is a special type of object in JavaScript
-- Arrays values are indexed from 0 and have special property length which stores the count of elements present in array
-
-```js
-// literal form
-const arr = [];
-```
-
-```js
-// consturctor form
-const arr = new Array();
-```
-
-```js
-// pre defined number of slots
-const arr = new Array(10);
-```
-
-```js
-// with values
-const arr = [1, true, "string"];
-```
-
-```js
-// constructor form with values
-const arr = new Array(1, true, "string");
-```
-
-###### References
-- https://javascript.info/array
-
-
-
-#### Q2
-### Write a program to iterate over an array and print all the values of it
-
-- Arrays can be iterated by using its index to fetch the values
-- Arrays also can be iterated with for each style loops
-
-```js
-for(let i =0; i < arr.length; i++){
- console.log(arr[i]);
-}
-```
-
-```js
-for(let index in arr){
- console.log(arr[index]);
-}
-```
-
-```js
-for(let value of arr){
- console.log(value);
-}
-```
-
-```js
-arr.forEach(val => console.log(val));
-```
-
-
-
-#### Q3
-### Write a program to append and prepend, single or multiple values in to an array
-
-- Values to the array can be appended using `push` method of array
-- Values to the array can be prepended using `unshift` method of array
-
-```js
-const arr = [2, 3];
-arr.push(4); // [2, 3, 4]
-arr.unshift(1); // [1, 2, 3, 4]
-```
-
-```js
-const arr = [3, 4];
-arr.push(5, 6); // [3, 4, 5, 6]
-arr.unshift(1, 2); // [1, 2, 3, 4, 5, 6]
-```
-
-```js
-const arr = [1, 2, 3];
-const otherArr = [4, 5, 6];
-arr.push(...otherArr); // [1, 2, 3, 4, 5, 6]
-arr.unshift(...arr); // [4, 5, 6, 1, 2, 3, 4, 5, 6]
-```
-
-###### Notes
-To remove the elements from the end of the array `pop` operation can be used but one element at a time. To remove the elements from the start of the array `shift` operation can be used but one element at a time
-
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift
-
-
-
-#### Q4
-### Show insertion and removal of elements can happen in the array for given index
-
-- Values of the array can be removed from any position using `splice` method of array
-- Values of the array can also be inserted to any position using `splice` method of array
-- 2nd argument is passed as 0 which inserts the elements without replacing
-- The values passed after 2nd argument are considered for insertion
-
-```js
-const arr = [1, 2, 2, 3];
-const position = 2;
-const count = 1;
-arr.splice(position, count); // [2]
-console.log(arr); // [1, 2, 3]
-```
-
-```js
-const arr = [1, 2, 4, 5];
-const position = 2;
-arr.splice(position, 0, 3);
-console.log(arr); // [1, 2, 3, 4, 5]
-```
-
-###### Notes
-'count' indicates the number of elements to be removed from the index 'position'. Multiple values can be inserted or removed using `splice`
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
-
-
-
-#### Q5
-### Show the different ways of emptying an array which has values
-
-- Array can be emptied by giving a new reference of an empty array
-- Setting the `length` of the array to 0 will automatically makes the array empty
-- `pop` operation on array can also be used to empty the array where each elements get removed
-
-```js
-arr = [];
-```
-
-```js
-arr.length = 0;
-```
-
-```js
-while(arr.length > 0){
- arr.pop();
-}
-```
-
-```js
-arr.splice(0, arr.length)
-```
-
-###### Notes
-`splice` operation used here to empty the array is a trick by passing the length of the array as argument, where all the elements of the array get removed
-
-###### References
-- https://www.javascripttutorial.net/array/4-ways-empty-javascript-array/
-
-
-
-#### Q6
-### Check if given input is an array or not
-
-- `Array.isArray` is a method which checks if the given argument is an array or not
-- Alternatively the `toString` method present on Object prototype can be used to check if it is an array
-
-```js
-Array.isArray(arr);
-```
-
-```js
-Object.prototype.toString.call(arr) === '[object Array]'
-```
-
-###### Notes
-`typeof` operator cannot be used to check if a value is an array or not because array is an object and `typeof arr` returns us "object"
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
-
-
-
-#### Q7
-### Write a function which can concatenate 2 arrays. If only one array is passed it will duplicate it
-
-- Function can take 2 arguments which concatenates arrays
-- 2nd array parameter can be defaulted to 1st array if the value is not passed
-
-```js
-function mergeArray(arr1, arr2 = arr1){
- return [...arr1, ...arr2];
-}
-```
-
-```js
-function mergeArray(arr1, arr2 = arr1){
- return arr1.concat(...arr2);
-}
-```
-
-```js
-function mergeArray(arr1, arr2 = arr1){
- arr1.push(...arr2);
- return arr1;
-}
-```
-
-###### Notes
-When 2nd argument is not passed, the case is same as duplicating the array
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
-
-
-
-#### Q8
-### Write a program to replace 3 center elements of the 1st array by center 3 elements of the 2nd array
-
-- `slice` method on array can be used to fetch the values of range in the array
-- `splice` method on array can be used to replace the value of range in the array
-
-```js
-const a = [1, 2, 3, 4, 5];
-const b = [4, 0, 0, 0, 8];
-
-const startPositionFor1stArray = a.length / 2 - 1;
-const startPositionFor2ndArray = b.length / 2 - 1;
-a.splice(startPositionFor1stArray, 3, ...b.slice(startPositionFor2ndArray, startPositionFor2ndArray + 3));
-```
-
-###### Notes
-The center most 3 values of array 'a' is replaced by 'b'
-
-
-
-#### Q9
-### Show how an array in JavaScript can act like a stack and queue
-
-- Stack is a 'Last In First Out' data structure can be achieved using `push` and `pop` operations
-- Queue is a 'First In First Out' data structure can be achieved using `push` and `shift` operations
-
-```js
-// To add the value to the stack
-arr.push(value);
-
-// To remove the value from the stack
-arr.pop();
-```
-
-```js
-// To add the value to the queue
-arr.push(value);
-
-// To remove the value from the queue
-arr.shift();
-```
-
-
-
-#### Q10
-### Sort the given array of integers in ascending or descending order
-
-- `sort` method sorts the elements of an array in place and returns the sorted array
-- It receives a function as an argument, which is used for comparision
-
-```js
-arr.sort((a, b)=> a - b); // ascending
-arr.sort((a, b)=> b - a); // descending
-```
-
-###### Notes
-If function is not passed an argument, default sorting will happen
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
-
-
-
-#### Q11
-### Sort the given array of objects in ascending order according the authors lastname
-```js
-// Example
-const books = [
- { name: "Harry Potter", author: "Joanne Rowling" },
- { name: "Warcross", author: "Marie Lu" },
- { name: "The Hunger Games", author: "Suzanne Collins" },
-]
-```
-- `sort` takes a function and expects the return value to be an integer for sorting
-- The last names of the author can be compared and the result can be returned for sorting
-
-```js
-books.sort((book1, book2) => {
- const authorLastName1 = book1.author.split(" ")[1];
- const authorLastName2 = book2.author.split(" ")[1];
- return authorLastName2 > authorLastName1 ? -1 : 1;
-});
-```
-
-###### Notes
-Returning a true or false will not work as the algorithm expects an integer value
-
-
-
-#### Q12
-### Square all the positive numbers of the array and return the output array
-
-- `filter` is the method on Array which can be used to filter. It receives a function which can return boolean to filter the elements
-- `map` is the method on Array which can be used to map the values to new values. It receives a function which can return the modified value
-
-```js
-const positiveArr = arr.filter((value) => value >= 0);
-const squaredPositiveArr = arr.map((value) => value * value);
-```
-
-```js
-const squaredPositiveArr = arr.filter((value) => value >= 0).map((value) => value * value);
-```
-
-###### Notes
-2nd solution uses method chaining where the return value from `filter` fuction is an array on which `map` method is being called
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
-
-
-
-#### Q13
-### Write a code to generate an array with range of numbers and shuffle them
-
-- An array of numbers in the range can be generated from a function which can take start and end value of the range
-- The shuffling can be achieved simply by sorting the array using a function which randomly returns positive or negative numbers
-- The shuffling of the values can be also done by picking a value from a random index from the current array and moving it in to a new array
-
-```js
-function rangeGenFunc(start = 1, end = 0) {
- const arr = [];
- for (let i = start; i <= end; i++) {
- arr.push(i);
- }
- return arr;
-}
-
-const arr = rangeGenFunc(1, 10); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-arr.sort(() => 0.5 - Math.random()); // [6, 8, 5, 10, 4, 3, 9, 2, 7, 1]
-```
-
-```js
-function* rangeGen(start = 1, end = 0) {
- for (let i = start; i <= end; i++){
- yield i;
- }
-}
-
-let arr = [...rangeGen(1, 10)]; // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-let shuffledArr = [];
-const length = arr.length;
-for (let i = 0; i < length; i++) {
- shuffledArr.push(...arr.splice(Math.floor(Math.random() * arr.length), 1));
-}
-
-console.log(shuffledArr) // [5, 4, 7, 10, 3, 6, 8, 2, 1, 9]
-```
-
-###### Notes
-2nd solution uses generator function to generate the range of values which can be converted to an array by spreading.
-
-
-
-#### Q14
-### Check if the user with the name "John" exists in the array of objects
-
-```js
-const doesJohnExist = arr.some((obj) => obj.name === "John");
-```
-
-```js
-const jonhObject = arr.find((obj) => obj.name === "John");
-const doesJohnExist = jonhObject ? true : false;
-```
-
-```js
-const jonhIndex = arr.findIndex((obj) => obj.name === "John");
-const doesJohnExist = jonhIndex < 0 ? false : true;
-```
-
-
-
-#### Q15
-### Generate an array of objects with properties id and full name from an array of objects where each object will have id, firstname and lastname
-
-- To manipulate array of objects `map` method can be used
-
-```js
-const employeesListWithFullName = arr.map((obj) => { return { id, fullName: obj.firstName + " " + obj.lastName } });
-```
-
-
-
-#### Q16
-### Create an array by removing all the holes of the array
-
-- Holes are `undefined` value present inside array
-- Holes do not get iterated in `filter` which will just fetch all the values except `undefined`
-
-```js
-const uniqueArr = arr.filter(value => true);
-```
-
-###### Notes
-Holes can be formed when an array value by index is deleted. Example: `delete arr[index]`
-
-
-
-#### Q17
-### Write a program to calculate the sum of all the values of an array
-
-- Sum of the values of an array can calculated by iterating and adding all the values of the array
-- `reduce` method of array can be used efficiently to calculate the sum with or without initial value
-
-```js
-const sum = arr.reduce((acc, value) => acc + value, 0);
-```
-
-```js
-const sum = arr.reduce((acc, value) => acc + value);
-```
-
-```js
-const sum = 0;
-for(let value of arr){
- sum = sum + value;
-}
-```
-
-###### Notes
-`reduce` method takes a function as 1st argument and initial value as 2nd argument. The return value of current iteration will be 1st argument for the next iteration along with the next element of the array
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
-
-
-
-#### Q18
-### Get the maximum value from a numbers array along with its index
-
-- `Math.max` is a method which returns maximum value from a given list of values
-- `reduce` can also be designed to return the maximum value of each comparision
-
-```js
-const max = Math.max(...arr);
-arr.indexOf(max); // position of max number
-```
-
-```js
-let max = a[0], position = 0;
-for(let index in arr){
- if(arr[index] > max){
- position = index
- max = value;
- }
-}
-
-position; // position of max number
-```
-
-```js
-const max = arr.reduce((a, b) => a < b ? a : b);
-arr.indexOf(max); // position of max number
-```
-
-###### Notes
-Though 2nd solution is verbose compared but has good performance
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min
-
-
-
-#### Q19
-### Find the number of occurences of minimum value in the numbers list
-
-- `filter` method can be used to fetch all the minimum values and we can get the count of those valuses
-
-```js
-const min = Math.min(...arr);
-minArr = arr.filter((value) => value === min);
-minArr.length; // count of minimum value occurences
-```
-
-
-
-#### Q20
-### Create an array of length n with all the values of it set to 10
-
-- `fill` is a method on Array prototype which fills all the slots of array with the value given passed as the argument
-
-```js
-const n = 5;
-const arr = new Array(n);
-arr.fill(10);
-```
-
-###### Notes
-If an object is passed the object reference is copied to all the slots and not the different objects
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill
-
-
-
-#### Q21
-### Optimize the given statements having lot of logical checks to use a compact and cleaner logic
-```js
-// Example1
-browser === "chrome" || browser === "firefox" || browser === "IE" || browser === "safari"
-
-// Example2
-browser !== "chrome" && browser !== "firefox" && browser !== "IE" && browser !== "safari"
-```
-
-- Examples can be modified to store the values of comparision in an array and check for the presence of value if it is present inside array
-
-```js
-// Example1
-// browser === "chrome" || browser === "firefox" || browser === "IE" || browser === "safari"
-
-const browserList = ["chrome", "firefox", "IE", "safari"];
-browserList.includes(browser);
-```
-
-```js
-// Example2
-// browser !== "chrome" && browser !== "firefox" && browser !== "IE" && browser !== "safari"
-
-const browserList = ["chrome", "firefox", "IE", "safari"];
-!browserList.includes(browser);
-```
-
-###### Notes
-Generally this use case can be implemented for `if` conditions
-
-
-
-#### Q22
-### Write a program to iterate over a 2 dimensional array and print all the values of it
-
-- Arrays can be iterated by using its index to fetch the values
-- Arrays also can be iterated with for each style loops, with one loop to iterate the rows and inside it for cells
-
-```js
-for (let i = 0; i < arr.length; i++) {
- for (let j = 0; j < arr[i].length; j++) {
- console.log(arr[i][j]);
- }
-}
-```
-
-```js
-for (let i = 0; i < arr.length; i++) {
- for (let j = 0; j < arr[i].length; j++) {
- console.log(arr[i][j]);
- }
-}
-```
-
-```js
-for (let rowArr of arr) {
- for (let value of rowArr) {
- console.log(value);
- }
-}
-```
-
-```js
-arr.forEach(rowArr => rowArr.forEach(val => console.log(val)));
-```
-
-
-
-#### Q23
-### Write a program to store values in to a set
-
-- Set lets us store unique values of any type
-- Set can be created empty & then added with values or can be initialized also
-
-```js
-const set = new Set();
-set.add(1);
-set.add(true);
-set.add("text");
-set.add(1);
-
-set; // 1, true, "text"
-```
-
-```js
-const set = new Set([1, 2, 3]);
-
-set; // 1, 2, 3
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
-
-
-
-#### Q24
-### Write a program to store values in to a map
-
-- `Map` holds key-value pairs and remembers the original insertion order of the keys
-- `Map` can be created empty & then added with values or can be initialized also with key-value pairs
-
-```js
-const map = new Map();
-map.set(1, 1000);
-map.set(true, false);
-map.set("text", "String");
-
-map; // [1, 1000] [true, false] ["text", "String"]
-```
-
-```js
-const map = new Map([[1, "One"], [2, "two"], [3, "three"]]);
-map; // [1, "One"] [2, "two"] [3, "three"]
-```
-
-###### Notes
-Unlike objects, `Map` can have any primitive or object as the key
-
-###### References
-
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
-
-
-
-#### Q25
-### Write a code to iterate over a set
-
-- `set` is an iterable object and can be iterated using for..of loop
-- `set` can also be iterated by simple `forEach` loop
-
-```js
-for(let val of set) console.log(val);
-```
-
-```js
-set.forEach(value => console.log(value));
-```
-
-
-
-#### Q26
-### Write a code to iterate over a map
-
-- `map` is an iterable object and can be iterated using for..of loop
-- `map` can also be iterated by simple `forEach` loop
-
-```js
-for(let val of map) console.log(val[0], val[1]);
-```
-
-```js
-for(let key of map.keys()) console.log(key, map.get(key));
-```
-
-```js
-map.forEach((value, key) => console.log(key, value));
-```
-
-
-
-#### Q27
-### Show how map is different from object to store key value pairs with coding example
-
-- Map does not contain any keys by default unlike objects which has keys from its prototype
-- Map's keys can be any value (including functions, objects, or any primitive) unlike object where keys are only strings
-- The keys in Map are ordered in a simple, straightforward way
-- The number of items in a Map is easily retrieved from its `size` property
-- Map is an iterable object
-
-```js
-map.set(1, 'Mapped to a number'); // primitive number as key
-map.set('1', 'Mapped to a string'); // string value as key
-map.set({}, 'Mapped to a object'); // object as key
-map.set([], 'Mapped to an array'); // array as key
-map.set(()=>{}, 'Mapped to a function'); // function as key
-```
-
-###### Notes
-Maps perform better than objects in most of the scenarios involving addition and removal of keys
-
-
-
-#### Q28
-### Write the code to remove the duplicates from the array
-
-- Set is a data structure which does not allow duplicate elements
-
-```js
-const set = new Set(...arr);
-const distinctArr = [...set];
-```
-
-
-
-#### Q29
-### Design a flat function which flattens an array to any depth
-
-- Flat function can be used to flatten the array by recursive call
-
-```js
-function flat(arr){
- const flatArr = [];
- arr.forEach((value) => {
- if(Array.isArray(value)){
- flat(value);
- }
- else{
- flatArr.push(value);
- }
- });
- return flatArr;
-}
-```
-
-
-
-#### Q30
-### Check if all the students of have passed or not (40 is the pass marks)
-
-- `every` is a method on Array prototype which returns true only if all the elements condition satisfies the condition
-
-```js
-const isAllPass = students.every((student) => student.marks >= 40);
-```
-
-
-
-#### Q31
-### Get the average of all the salaries which is greater than 10000 from the department of "IT" from the array of objects)
-
-```js
-const itEmployeesWithSalaryGT10K = employees.filter((employee) => employee.salary > 10000 && employee.dept === 'IT );
-const itTotalSalaryGT10K = itEmployeesWithSalaryGT10K.reduce((acc, value) => acc + value, 0);
-const itAvgSalaryGT10K = itTotalSalaryGT10K / itEmployeesWithSalaryGT10K.length;
-```
-
-
-
-#### Q32
-### Extract the list of all the elements from the list of numbers given in 2 arrays
-
-- The union array will be the result if all the elements from the 2 arrays are picked
-
-```js
-const set1 = new Set(...arr1);
-const set2 = new Set(...arr2);
-const distinctArr = [...set1, ...set2];
-```
-
-
-
-#### Q33
-### Get the list of all distinct elements which are present in both list of numbers
-
-- The intersection array will be the result if the common elements from the 2 arrays are picked
-
-```js
-const intersectionArr = arr1.filter(value => arr2.includes(value));
-const distinctIntersectionArr = [...new Set(intersectionArr)];
-```
-
-```js
-const set1 = new Set(arr1);
-const set2 = new Set(arr2);
-const distinctIntersectionArr = [...set1].filter(value => set2.has(value));
-```
-
-
-
-#### Q34
-### Extract list of elements present only in the first list given.
-
-- The only present elements of 1st list will be the result when all the elements of 1st list not present in the 2nd are chosen
-
-```js
-const set1 = new Set(arr1);
-const set2 = new Set(arr2);
-const intersectionArr = [...set1].filter(value => !set2.has(value));
-```
-
-###### Notes
-Elements of 2nd list only can be obtained by checking for all the elements of lis 2 which are not present in list1
-
-
-
-#### Q35
-### Create a function named "average" which can calculate the average of an array and should be available to be called from any Array object.
-
-- The function added to Array prototype are accessible to all the objects of Array
-
-```js
-Array.prototype.average = function (){
- let total = 0;
-
- for(let index in this) {
- total += this[index];
- }
- return total / this.length;
-}
-```
-
-
-
-#### Q36
-### Write a program to polyfill `filter` functionality of the Array
-
-- `filter` iterates over the all values of array and passes value, index and array (itself) as the arguments
-- Function returns a new array which filtering the values of the original array
-
-```js
-if (!Array.prototype.filter) {
- Array.prototype.filter = function(callback) {
-
- if(typeof callback !== "function")
- throw new Error("Argument passed has to be a function");
-
- let newArray = [];
-
- for(let index in this) {
- if(callback(this[index], index, this)){
- newArray.push(this[index]);
- }
- }
- return newArray;
- }
-}
-```
-
-###### Notes
-The solution is a simple polyfill of `filter` and not intended to handle all the corner scenarios
-
-
-
-#### Q37
-### Write a program to polyfill `map` functionality of the Array
-
-- `map` iterates over the all values of array and passes value, index and array (itself) as the arguments
-- Function returns a new array which is same as the length of the original array
-
-```js
-if (!Array.prototype.map) {
- Array.prototype.map = function(callback) {
- if(typeof callbak !== "function")
- throw new Error("Argument passed has to be a function");
-
- let newArray = [];
-
- for(let index in this) {
- newArray.push(callback(this[index], index, this));
- }
- return newArray;
- }
-}
-```
-
-###### Notes
-The solution is a simple polyfill of `map` and not intended to handle all the corner scenarios
-
-
-
-#### Q38
-### Write a program to polyfill `reduce` functionality of the Array
-
-- `reduce` iterates over the all values of array and passes value, index and array (itself) as the arguments
-- `reduce` accepts an optional initial value which when not provided can be skipped
-- Function returns a single value after all the iteration
-
-```js
-if (!Array.prototype.reduce) {
- Array.prototype.reduce = function(callback, init) {
- let startPosition = 0;
- let accumulator = init ?? this[startPosition++];
-
- for(let index = startPosition; index < this.length; index++) {
- accumulator = callback(accumulator, this[index], index, this);
- }
- return accumulator;
- }
-}
-```
-
-###### Notes
-The solution is a simple polyfill of `reduce` and not intended to handle all the corner scenarios
-
-
-
-#### Q39
-### Write a code to eliminate duplicate objects in an array where each object has an 'id' property which can be used to identify the object and the duplicate object with lower rank to be removed
-```js
-// Example
-const arr = [
- {
- id: 1,
- name: 'emp1',
- rank: 4,
- },
- {
- id: 2,
- name: 'emp2',
- rank: 1,
- },
- {
- id: 2,
- name: 'emp2',
- rank: 2, // this is a duplicate object (id = 2) and has lower rank
- },
- {
- id: 3,
- name: 'emp3',
- rank: 3,
- },
-];
-```
-
-- The duplicate objects cannot be removed using `Set` as the 2 objects with same structure and data have different references
-- `Map` can be used to have 'id' as the key and object as value
-- If 'id' is already present in the array, object with the higher rank can be retained
-
-```js
-const map = new Map();
-
-arr.forEach(obj => {
- if (map.has(obj.id)) {
- if (obj.rank > map.get(obj.id)) {
- map.set(obj.id, obj);
- }
- } else {
- map.set(obj.id, obj);
- }
-});
-
-distinctArr = [...map.values()];
-```
-
-
-
-#### Q40
-### Create an array which will only accept string values. (Homogeneous array of strings)
-
-- Array in JavaScript a collection of values of any type by default
-- Proxy can be used to validate and insert to the array only if the value satisfies the condition using `set` trap
-
-```js
-var stringsArr = [];
-
-var stringsArr = new Proxy(stringsArr, {
- set(target, prop, receiver){
- if(typeof receiver === "string"){
- target[target.length] = receiver;
- }
- return true;
- }
-});
-
-// driver code
-stringsArr.push("Hello", 5, {}, "world", true, [1, 2, 3]);
-stringsArr; // ["Hello", "world"]
-```
-
-###### Notes
-The functionality of the code can be modified to make the array accept any one or more kind of values only
-
-
-
-#### Q41
-### Create a Proxy object through which the array can be accessed as usual but also allow to access the values through negative indices
-```js
-// Example
-let arr = [10, 20, 30];
-
-arr[-1]; // 30
-arr[-2]; // 20
-```
-
-- `get` trap of proxy can be used to map the negative index to the valid array position
-
-```js
-arr = new Proxy(arr, {
- get(target, handler) {
- if (handler < 0) return target[target.length + Number(handler)];
- else return target[handler];
- },
-});
-```
-
-
-
-[[↑] Back to top](#home)
diff --git a/challenges/functions-challenges.md b/challenges/functions-challenges.md
new file mode 100644
index 0000000..197961f
--- /dev/null
+++ b/challenges/functions-challenges.md
@@ -0,0 +1,644 @@
+
+
+## JavaScript interview code challenges on Functions - challenges
+
+1. [Design a Calulator interface for 2 number inputs which can perform sum, difference, product and dividend whenever invoked on the same interface](#Q1)
+1. [Design a private counter function which exposes increment and retrive functionalities](#Q2)
+1. [Write a polyfill for bind function](#Q3)
+1. [Write a function which will create a function bounded to the context like `bind`, but can be overridden when the context is set explicitly](#Q4)
+1. [Write a function which helps to achieve multiply(a)(b) and returns product of a and b](#Q5)
+1. [Create a function which takes another function as an argument and makes it eligible for currying or partial application](#Q6)
+1. [Design a function which helps to do debouncing](#Q7)
+1. [Design a function which helps to do throttling](#Q8)
+1. [Design an interface which limits the number of function calls by executing the function once for a given count of calls](#Q9)
+1. [Write a singleton function to create an object only once](#Q10)
+1. [Design a function with toggle functionality for given list of inputs where toggle function accepts list of values to be toggled upon](#Q11)
+1. [Create a range function which returns an array for the provided inputs as start and end](#Q12)
+1. [Write a function which takes a function as an argument to achieve memoization](#Q13)
+1. [Create a single function which can perform sum(a, b, c), sum(a, b)(c), sum(a)(b, c) and sum(a)(b)(c) and returns sum of a, b and c](#Q14)
+1. [Design a function which can keep recieving the arguments on each function call and returns the sum when no argument is passed](#Q15)
+1. [Create an interface for a function such that whenever a function is triggered the system should log the time. Do not modify the function code](#Q16)
+1. [Create an interface exposing subscribe and publish functionality, which allows publishing data which in turn invokes all the subscribers with the data](#Q17)
+
+---
+
+#### Q1
+### Design a Calulator interface for 2 number inputs which can perform sum, difference, product and dividend whenever invoked on the same interface
+```js
+// Example
+const calc12And5 = Calculator(12, 5);
+calc12And5.sum(); // 17
+calc12And5.difference(); // 7
+calc12And5.product(); // 60
+calc12And5.dividend(); // 2
+```
+
+- Simple revealing module pattern can be used which receives inputs and executes different operations exposed through functions
+
+```js
+function Calulator(num1, num2){
+
+ function sum(){
+ return num1 + num2;
+ }
+
+ function difference(){
+ return num1 - num2;
+ }
+
+ function product(){
+ return num1 * num2;
+ }
+
+ function dividend(){
+ return Math.floor(num1 / num2);
+ }
+
+ return { sum, difference, product, dividend };
+}
+```
+
+###### Notes
+The solution provided is one of the way to achieve the interface. The design and solution can vary
+
+###### References
+- https://eloquentjavascript.net/10_modules.html
+
+
+
+#### Q2
+### Design a private counter function which exposes increment and retrive functionalities
+
+```js
+function privateCounter(){
+ var count = 0;
+ return {
+ increment: function(val = 1){
+ count += val;
+ }
+ retrieve: function(){
+ return count;
+ }
+ }
+}
+
+// driver code
+const counter = privateCounter();
+counter.increment();
+counter.increment();
+counter.retrieve(); // 2
+counter.increment(5);
+counter.increment();
+counter.retrieve(); // 8
+```
+
+###### Notes
+'increment' function takes an argument to increment if passed else which is set to 1 (increments by 1)
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
+
+
+
+#### Q3
+### Write a polyfill for bind function
+
+- The `bind` method creates a new function that, when called, has its this keyword set to the provided context
+
+```js
+if(!Function.prototype.bind){
+ Function.prototype.bind = function(context){
+ var fn = this;
+ var fnArgs = Array.prototype.slice.call(arguments, 1);
+
+ return function(){
+ var allArgs = funcArgs.concat(Array.prototype.slice.call(arguments))
+ fn.apply(context, allArgs);
+ };
+ }
+}
+```
+
+###### Notes
+This is a simple polyfill for bind without handling corner cases. It does not work when using the new operator
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
+
+
+
+#### Q4
+### Write a function which will create a function bounded to the context like `bind`, but can be overridden when the context is set explicitly
+
+- The functionality is similar to `bind` with exception that if there is a context set during the execution it will override
+
+```js
+function softBind(fn, context) {
+ var fnArgs = Array.prototype.slice.call(arguments, 2);
+
+ return function() {
+ var allArgs = fnArgs.concat(Array.prototype.slice.call(arguments));
+
+ // override the context to incoming context if it is not undefined, null or window
+ var context = (!this || this === window) ? obj : this;
+ fn.apply(context, allArgs);
+ };
+}
+```
+
+###### Notes
+This functionality is also known as 'Soft Binding'
+
+###### References
+- https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch2.md#softening-binding
+- https://gist.github.com/getify/9043478
+
+
+
+#### Q5
+### Write a function which helps to achieve multiply(a)(b) and returns product of a and b
+```js
+// Example
+multiply(2)(4); // 8
+multiply(5)(3); // 15
+```
+
+- The implementation of this can be achieved by calling a function which returns a function
+
+```js
+function multiply(num1){
+ return function (num2){
+ return num1 * num2;
+ }
+}
+```
+
+###### References
+- https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983
+
+
+
+#### Q6
+### Create a function which takes another function as an argument and makes it eligible for currying or partial application
+
+- Function can take another function as argument and accept the arguments on the returned functions till the expected arguments are reached
+- The arguments can be 1 or multiple, and the actual function will be called once the count of expected arguments are reached
+
+```js
+function curryFunc(fn) {
+ return function curry(...args) {
+ if (fn.length <= args.length) {
+ return fn.apply(this, args);
+ } else {
+ return function (...args2) {
+ return curry.apply(this, args.concat(args2));
+ };
+ }
+ };
+}
+
+// driver code
+let sum = curryFunc(function (a, b, c, d) {
+ return a + b + c + d;
+});
+
+sum(1)(2)(3)(4); // called like curried function
+sum(1,2)(3,4); // called like partial application
+```
+
+###### References
+- https://javascript.info/currying-partials#advanced-curry-implementation
+
+
+
+#### Q7
+### Design a function which helps to do debouncing
+
+- The `debounce` function forces a function to wait a certain amount of time before running again
+- The function is built to limit the number of function calls to improve the performance
+- Debounce function design can take function (to be debounced), delay and the optional context
+
+```js
+function debounce(fn, delay, context){
+ let timer;
+
+ return function(...args){
+ if(timer) clearTimeout(timer);
+
+ context = this ?? context;
+ timer = setTimeout(()=>{
+ fn.apply(context, args);
+ }
+ , delay);
+ }
+}
+```
+
+###### Notes
+Context is replaced while debounce function call in presence of a context. If not, context set during the `debounce` function call is used.
+
+###### References
+- https://www.youtube.com/watch?v=Zo-6_qx8uxg
+
+
+
+#### Q8
+### Design a function which helps to do throttling
+
+- The `throttling` function forces a function to run once in an amount of time for one or multiple calls
+- The function is built to limit the number of function calls to improve the performance
+- Throttling function design can take function (to be throttled), delay and the optional context
+
+```js
+function throttle(fn, delay, context){
+ let timer;
+ let lastArgs;
+
+ return function(...args){
+ lastArgs = args;
+ context = this ?? context;
+
+ if(timer) return;
+
+ timer = setTimeout(()=>{
+ fn.apply(context, lastArgs);
+ clearTimeout(timer);
+ }
+ , delay);
+ };
+}
+```
+
+###### Notes
+Last arguments to the throttled function is saved so that most recent arguments will be used for throttled function execution (unlike debouncing where it is taken care due to its way of execution)
+
+###### References
+- https://www.youtube.com/watch?v=81NGEXAaa3Y
+
+
+
+#### Q9
+### Design an interface which limits the number of function calls by executing the function once for a given count of calls
+
+- function forces a function run to for specific number of times in a given number of execution calls
+- The function is built to limit the number of times a function is called
+- Throttling function design can take function (to be throttled), delay and the optional context
+
+```js
+function sampler(fn, count, context){
+ let counter = 0;
+
+ return function(...args){
+ lastArgs = args;
+ context = this ?? context;
+
+ if(++counter !== count) return;
+
+ fn.apply(context, args);
+ counter = 0;
+ };
+}
+```
+
+###### Notes
+Sampling is different from throttling in the way that sampling limits the execution by executing function once in a given number of calls where as throttling limits the execution by executing function once in a given amount of time
+
+###### References
+- https://rxjs.dev/api/operators/sample
+
+
+
+#### Q10
+### Write a singleton function to create an object only once
+
+- Singleton is a design pattern which restricts the creation of only one object from a given interface
+- When requested multiple times, same object is returned
+
+```js
+var Singleton = (function () {
+ var instance;
+
+ function createInstance() {
+ var object = new Object("I am the instance");
+ return object;
+ }
+
+ return {
+ getInstance: function () {
+ if (!instance) {
+ instance = createInstance();
+ }
+ return instance;
+ }
+ };
+})();
+
+// driver code
+const instance1 = Singleton.getInstance();
+const instance2 = Singleton.getInstance();
+```
+
+###### Notes
+Here both 'instance1' and 'instace2' are referencing to the same object
+
+###### References
+- https://www.dofactory.com/javascript/design-patterns/singleton
+
+
+
+#### Q11
+### Design a function with toggle functionality for given list of inputs where toggle function accepts list of values to be toggled upon
+```js
+// Example
+var hello = toggle("hello");
+var onOff = toggle("on","off");
+var speed = toggle("slow","medium","fast");
+
+hello(); // "hello"
+hello(); // "hello"
+
+onOff(); // "on"
+onOff(); // "off"
+onOff(); // "on"
+
+speed(); // "slow"
+speed(); // "medium"
+speed(); // "fast"
+speed(); // "slow"
+```
+
+- Toggle functionality can be obtained by returning the next value cyclically on each call to the function
+- The toggle function will return another function which maintains the closure over the values with which it was initialized
+
+```js
+function toggle(...values){
+ let state = -1;
+ const length = values.length;
+ return function(){
+ state = (state + 1) % length;
+ return values[state];
+ }
+}
+```
+
+###### References
+- https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/apB.md#closure-part-2
+
+
+
+#### Q12
+### Create a range function which returns an array for the provided inputs as start and end
+```js
+// Example
+range(3, 6) // [3, 4, 5, 6]
+range(3)(5) // [3, 4, 5]
+range(3)(0) // []
+```
+
+- Range functionality can be obtained by returning the an array from start to end both inclusive
+- In case if 2nd argument is not passed, function will return another function which calls itself with once both the values are obtained
+
+```js
+function range(start, end) {
+ if (end === undefined) {
+ return function (end) {
+ return range(start, end);
+ };
+ }
+
+ const arr = [];
+ for (let i = start; i <= end; i++) {
+ arr.push(i);
+ }
+ return arr;
+}
+```
+
+###### References
+- https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/get-started/apB.md#appendix-b-practice-practice-practice
+
+
+
+#### Q13
+### Write a function which takes a function as an argument to achieve memoization
+
+- Memoization is an optimization technique used primarily to speed up the programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again
+- Function can be designed to use a cache storage (using `map` or `object`) which stores the values of function output against the input
+
+```js
+function memoize(fn) {
+ const cache = new Map();
+ return function () {
+ const key = JSON.stringify(arguments);
+
+ // if the caculations have already been done for inputs, return the value from cache
+ if (cache.has(key)) {
+ return cache.get(key);
+ } else {
+ // call the function with arguments and store the result in cache before returning
+ cache.set(key, fn(...arguments));
+ return cache.get(key);
+ }
+ };
+}
+
+// driver code
+let factorial = memoize(function fact(value) {
+ return value > 1 ? value * fact(value - 1) : 1;
+});
+
+factorial(5); // 120 (output is calculated by calling the function)
+factorial(5); // 120 (output is returned from the cache which was stored from previous calculations)
+```
+
+###### Notes
+Stringification of arguments done in order for the function to work for multiple arguments
+
+###### References
+- https://codeburst.io/understanding-memoization-in-3-minutes-2e58daf33a19
+
+
+
+#### Q14
+### Create a single function which can perform sum(a, b, c), sum(a, b)(c), sum(a)(b, c) and sum(a)(b)(c) and returns sum of a, b and c
+```js
+// Example
+sum(2)(4)(6); // 12
+sum(3, 2)(5); // 10
+sum(4)(-10, -6); // -12
+sum(6, -3, 1); // 4
+```
+
+- Sum functionality can be obtained by returning the sum when all the arguments are present
+- The cases when only 1 or 2 arguments are passed need to be managed and handled
+
+```js
+function sum(a, b, c){
+ if(a !== undefined && b !== undefined && c !== undefined){
+ return a + b + c;
+ }
+ if(a !== undefined && b !== undefined){
+ return function(c){
+ return sum(a, b, c);
+ }
+ }
+ return function(b, c){
+ if(b !== undefined && c !== undefined){
+ return sum(a, b, c);
+ }
+ return function(c){
+ return sum(a, b, c);
+ }
+ }
+}
+```
+
+```js
+const countOfValues = 3;
+
+function sum() {
+ const args = arguments;
+
+ if (args.length === countOfValues) {
+ return Array.prototype.reduce.call(args, (a, b) => a + b);
+ }
+
+ return function () {
+ return sum(...args, ...arguments);
+ };
+}
+```
+
+###### Notes
+2nd approach is generic technique and can be used customized for any number of values
+
+
+
+#### Q15
+### Design a function which can keep recieving the arguments on each function call and returns the sum when no argument is passed
+
+- The function can be designed to return another function which maintains the closure over the previous sum value
+- The check for breaking condition can be added using the argument check for `undefined`
+- 3rd solution uses the property on function to store the total which will be updated on each call hence the same function can be returned
+
+```js
+// Example
+sum(2)(4)(6)(1)(); // 13
+sum(2)(4)(); // 6
+sum(3)(); // 3
+```
+
+- Sum functionality can be obtained by returning the recursively calling till the 2nd parameter value is undefined
+
+```js
+function sum(a) {
+ return function (b) {
+ if (b === undefined) {
+ return a;
+ }
+ return sum(a + b);
+ };
+}
+```
+
+```js
+const sum = a => b => b === undefined ? a : sum(a + b);
+```
+
+```js
+function sum(a) {
+ if (typeof a === 'undefined') {
+ return sum.total;
+ }
+ sum.total = (sum.total ?? 0) + a;
+ return sum;
+}
+```
+
+###### Notes
+In the code value is checked if it is undefined reason being 0 is a falsy value and `b ? a : sum(a + b)` code fails when one of the argument is 0. Example: `sum(4)(3)(0)(2)()`
+
+###### References
+- https://www.youtube.com/watch?v=D5ENjfSkHY4
+
+
+
+#### Q16
+### Create an interface for a function such that whenever a function is triggered the system should log the time. Do not modify the function code
+
+- Function call can be handled using Proxy in JavaScript
+- `apply` keyword in proxy can be used to achieve the functionality without modifying the existing function code
+
+```js
+function generateSecretObject(key, value) {
+ return { [key]: value };
+}
+
+generateSecretObject = new Proxy(generateSecretObject, {
+ apply(target, context, args) {
+ console.log(`${target.name} function is accessed at ${new Date()}`);
+ return target.apply(context, args);
+ },
+});
+
+// driver code
+const user = {
+ username: "0001",
+ generateSecretObject
+};
+generateSecretObject("username", "Password"); // "generateSecretObject function is accessed at {time}"
+```
+
+###### Notes
+This technique is helpful in logging or managing the data being passed to & returned from function without modifying the actual function code especially when function is a part of library or framework
+
+
+
+#### Q17
+### Create an interface exposing subscribe and publish functionality, which allows publishing data which in turn invokes all the subscribers with the data
+
+- A simple module with publish and subscribe function can be exposed to achieve such functionality
+- List of subscribers can be maintained in an array and can be invoked in loop on each publish
+
+```js
+function pubSub() {
+ const subscribers = [];
+
+ function publish(data) {
+ subscribers.forEach(subscriber => subscriber(data));
+ }
+
+ function subscribe(fn) {
+ subscribers.push(fn);
+ }
+
+ return {
+ publish,
+ subscribe,
+ };
+}
+
+// driver code
+const pubSubObj = pubSub();
+pubSubObj.subscribe(data => {
+ console.log('Subscriber 1: ' + data);
+});
+pubSubObj.subscribe(data => {
+ console.log('Subscriber 2: ' + data);
+});
+
+// all subscribers will be called with the data on publish
+pubSubObj.publish('Value is 10');
+```
+
+###### Notes
+This is a well known JavaScript pattern called as __Publish/Subscribe Pattern__
+
+###### References
+- https://jsmanifest.com/the-publish-subscribe-pattern-in-javascript/
+
+
+
+[[↑] Back to top](#home)
\ No newline at end of file
diff --git a/challenges/functions-concepts.md b/challenges/functions-concepts.md
new file mode 100644
index 0000000..5c97015
--- /dev/null
+++ b/challenges/functions-concepts.md
@@ -0,0 +1,685 @@
+
+
+## JavaScript interview code challenges on Functions - concepts
+
+1. [Write a function which returns another function and execute it after calling](#Q1)
+1. [Write a function which executes another function recieved as an argument](#Q2)
+1. [Create a function having no parameters declared and print all the arguments passed to it](#Q3)
+1. [Write a function which executes only if the number of arguments match the number of parameters the function is expecting](#Q4)
+1. [Design a function which can recieve variable number of arguments in parameters and print them](#Q5)
+1. [Show the most common ways of creating functions in JavaScript](#Q6)
+1. [Code the different forms of arrow functions for varying number of parameters](#Q7)
+1. [Write a program where hoisting can be visualized](#Q8)
+1. [Code an Immediately Invoked Function Expression (IIFE) and show the different ways of executing it](#Q9)
+1. [Create an IIFE which receives arguments and executes](#Q10)
+1. [Show the usage of IIFE to set a value of a variable](#Q11)
+1. [Write a function which can return multiple values from a function](#Q12)
+1. [Write a function which can set default value to the parameters of function when an argument is not passed. Also show how to use exisiting parameters to set the value of another parameter](#Q13)
+1. [Show the usage of call, apply and bind with practical example](#Q14)
+1. [Show the usage of function which can used as a constructor](#Q15)
+1. [Show the procedure of creating object using a factory function](#Q16)
+1. [Achieve prototypal inheritance using functions to create objects in JavaScript](#Q17)
+1. [Write a code to show the differences between the techniques, currying and partial application](#Q18)
+1. [Write a function to copy functions of an object to another object (mixin)](#Q19)
+1. [Show the usage Proxy for function](#Q20)
+
+---
+
+#### Q1
+### Write a function which returns another function and execute it after calling
+
+- Functions can be declared, executed or returned inside another function
+
+```js
+function higherOrderFunction(){
+ function displayHello(){
+ console.log("Hello")
+ }
+ return displayHello;
+}
+
+// driver code
+var func = higherOrderFunction();
+func(); // hello
+```
+
+###### Notes
+Function can also be stored in variables like other values in JavaScript
+
+###### References
+- https://eloquentjavascript.net/05_higher_order.html
+- https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function
+
+
+
+#### Q2
+### Write a function which executes another function recieved as an argument
+- Functions can be passed as arguments to another functions
+- Passing the function as argument will pass its reference hence no parenthesis
+
+```js
+function callbackExecutor(callback){
+ if(typeof callback === "function"){
+ callback();
+ }
+}
+
+
+// driver code
+function callbackFunc(){
+ console.log("Callback function executed");
+}
+
+callbackExecutor(callbackFunc); // Callback function executed
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Glossary/Callback_function
+
+
+
+#### Q3
+### Create a function having no parameters declared and print all the arguments passed to it
+
+- When a function is invoked the arguments passed to it are accessible using the defualt object called "arguments"
+- Numbers starting from 0 is set as key of the object "arguments" corresponding to each argument in the order
+- `arguments` object will have length property as well which gives count of arguments passed
+
+```js
+function func(){
+ for(let key in arguments){
+ console.log(arguments[key]);
+ }
+}
+
+// driver code
+func(1, "Hello", true);
+```
+
+```js
+function func(){
+ for(let value of arguments){
+ console.log(value);
+ }
+}
+
+// driver code
+func(1, "Hello", true);
+```
+
+###### Notes
+Though the keys of arguments object look like numbers, "arguments" is not an array. Arrow functions will not have arguments object
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
+
+
+
+#### Q4
+### Write a function which executes only if the number of arguments match the number of parameters the function is expecting
+
+- The number of parameters declared in a function can be obtained by accessing the length property of the function
+
+```js
+function func(a, b, c){
+ if(func.length === arguments.length){
+ console.log("Number of arguments passed match the expected arguments");
+ }
+ else {
+ throw new Error("Number of arguments passed do not match the expected arguments");
+ }
+}
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length
+
+
+
+#### Q5
+### Design a function which can recieve variable number of arguments in parameters and print them
+
+```js
+function varArgsFunc(...params){
+ params.forEach(function(value, index){
+ console.log(index, ": ", value);
+ })
+}
+
+// driver code
+varArgsFunc("Hello", ",", "World", "!!!");
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
+
+
+
+#### Q6
+### Show the most common ways of creating functions in JavaScript
+
+- The functions are most commonly created as function statements, function expression and arrow functions
+- Function statements get hoisted unlike function expressions
+
+```js
+// Regular function as a function statement
+function functionName(params) {
+ //code block
+}
+```
+
+```js
+// Regular function as a function expression
+const functionName = function (params) {
+ //code block
+}
+```
+
+```js
+// Arrow function as a function expression
+const arrowFunctionName = (params) => {
+ //code block
+}
+```
+
+###### Notes
+As the arrow functions are not verbose, majority of developers prefer to create arrow functions for quick coding
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
+
+
+
+#### Q7
+### Code the different forms of arrow functions for varying number of parameters
+
+- Arrow functions provide simpler syntax over `function` keyword functions
+- Arrow functions with single parameter, round brackets are optional
+- Arrow functions with single statement with return, flower brackets and return keywords are optional
+
+```js
+const noArgsFunc = () => {
+ return "No args passed"
+};
+```
+
+```js
+const singleArgFunc = (arg1) => "Argument is " + arg1;
+```
+
+```js
+const singleArgFunc = arg1 => {
+ console.log("Argument is " + arg1);
+ return arg1;
+};
+```
+
+```js
+const twoArgsFunc = (arg1, arg2) => {
+ return arg1 + arg2;
+}
+```
+
+```js
+const threeArgsFunc = (arg1, arg2, arg3) => {
+ console.log("Sum is " + (arg1 + arg2 + arg3));
+ return true;
+}
+```
+
+###### Notes
+Arrow functions are also called fat arrow functions
+
+###### References
+- https://developer.mozilla.org/en-US/docs/web/JavaScript/Reference/Operators/function
+
+
+
+#### Q8
+### Write a program where hoisting can be visualized
+
+- The function statement and variable declared with `var` are accessible before it appears in the code
+- Declarations are put into memory before it executes any code segment that allows us to use a function before you declare it in your code
+- In hoisting the hoisted items are accessible in the scope it is declared
+- Function expressions do not get hoisted
+
+```js
+num1 = 10;
+printHello();
+
+var num1;
+function printHello(){
+ console.log("Hello");
+}
+
+var nonHoistedFunc = function(){
+ console.log("Hello");
+}
+```
+
+###### Notes
+Hoisting was thought up as a general way of thinking about how execution contexts work in JavaScript. In reality, code does not get hoisted, but affect is seen due to compilation and execution phases followed by JavaScript compiler
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
+
+
+
+#### Q9
+### Code an Immediately Invoked Function Expression (IIFE) and show the different ways of executing it
+
+- IIFE is a JavaScript function that runs as soon as it is defined
+- IIFE prevents polluting the global scope
+
+```js
+(function IIFE(){
+ console.log("I am an Immediately invoked function");
+})();
+```
+
+```js
+(function IIFE(){
+ console.log("I am an Immediately invoked function");
+}());
+```
+
+```js
++function IIFE(){
+ console.log("I am an Immediately invoked function");
+}();
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Glossary/IIFE
+
+
+
+#### Q10
+### Create an IIFE which receives arguments and executes
+
+- Arguments can be passed normally to an IIFE like we pass to while calling regular functions
+- Multiple arguments can be passed similar to function invokation with arguments
+
+```js
+(function IIFE(param1, param2){
+ console.log("I am an Immediately invoked function");
+ console.log("Parameter 1: " + param1);
+ console.log("Parameter 2: " + typeof param2);
+ console.log("Parameter 2 output: " + param2());
+})("hello", function(){ return "I am a string from a function passed to IIFE"; });
+```
+
+###### Notes
+A string and a function is passed as arguments to the IIFE
+
+
+
+#### Q11
+### Show the usage of IIFE to set a value of a variable
+
+- IIFE can be directly executed when it is used as an expression against assignment to a variable
+
+```js
+var randomNumber = function (){
+ return Math.floor(Math.random() * 100);
+}();
+```
+
+
+
+#### Q12
+### Write a function which can return multiple values from a function
+
+- Function in general is designed to return a single value.
+- Generators are special type of functions which returns iterator which in turn can be used to send & receive values.
+
+```js
+function multipleValueReturnFunc(){
+ const a = 5, b = 10;
+ return [a, b];
+}
+
+// driver code
+const [x, y] = multipleValueReturnFunc();
+```
+
+```js
+function multipleValueReturnFunc(){
+ const a = 'Java', b = 'Script';
+ return {
+ a, b
+ };
+}
+
+// driver code
+const {x, y} = multipleValueReturnFunc();
+```
+
+```js
+function* multipleValueReturnFunc(){
+ const a = 5, b = 10;
+ yield a;
+ yield b;
+}
+
+// driver code
+const iterator = multipleValueReturnFunc();
+const x = iterator.next().value;
+const y = iterator.next().value;
+```
+
+###### Notes
+Array and object are used in the programs to contain multiple values
+
+
+
+#### Q13
+### Write a function which can set default value to the parameters of function when an argument is not passed. Also show how to use exisiting parameters to set the value of another parameter
+
+- Default function parameters allow named parameters to be initialized with default values if no value or undefined is passed
+
+```js
+function defaultValueFunc(num = 10, num2 = 20, string = "Hello", bool = false, sum = num1 + num2 ){
+ console.log(num, string, bool, sum);
+}
+
+// driver code
+defaultValueFunc(); // 10, 20, false, 30
+defaultValueFunc(4, 8); // 4, 8, false, 12
+defaultValueFunc(10, 4, true); // 10, 4, true, 14
+defaultValueFunc(5, 6, false, 11); // 5, 6, false, 11
+defaultValueFunc(undefined, undefined, false); // 10, 20, false, 30
+```
+
+###### Notes
+The default values are set only for missing or `undefined`. `null` and other falsy values are considered as valid arguments and default will not be set
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
+
+
+
+#### Q14
+### Show the usage of call, apply and bind with practical example
+
+- 'call' is a method on function prototype and is used to set the context of the function by passing it as 1st argument followed by the arguments
+- 'apply' is a method on function prototype and is used to set the context of the function by passing it as 1st argument followed by the array of arguments
+- 'bind' is a method on function prototype and is used to create a new function with the context as the 1st argument followed by the arguments
+
+```js
+function displayThisValue(param1, param2) {
+ console.log(this.value, param1, param2);
+}
+
+const obj = {
+ value: 10
+}
+const valueArr = [20, 30];
+
+// No context set
+displayThisValue(20, 30); // undefined, 20, 30
+
+// 'obj' is set as the context using 'call'
+displayThisValue.call(obj, ...valueArr); // 10, 20, 30
+
+// 'obj' is set as the context using 'apply'
+displayThisValue.apply(obj, valueArr); // 10, 20, 30
+
+// No context set
+setTimeout(displayThisValue, 1000, ...valueArr); // undefined, 20, 30
+
+// 'obj' is set as the context using 'bind'
+setTimeout(displayThisValue.bind(obj), 1000, ...valueArr); // 10, 20, 30
+setTimeout(displayThisValue.bind(obj, ...valueArr), 1000); // 10, 20, 30
+```
+
+###### Notes
+The context inside the function can be accessed using `this` keyword
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
+- https://javascript.info/bind
+
+
+
+#### Q15
+### Show the usage of function which can used as a constructor
+
+- Function can be used to like a constructor by calling it with a `new` keyword
+- Constructor function is a normal function but generally used to create object and may also have functions in its prototype
+- Constructor function is generally preferred to start with Uppercase letter which is not mandatory
+- The return from the constructor function is new object created which is accessed with `this` inside the function
+- Constructor function can return an explicit object as well
+
+```js
+function Employee(id){
+ this.id = id;
+}
+
+Employee.prototype.setSalary = function(salary){
+ this.salary = salary;
+}
+
+Employee.prototype.getSalary = function(){
+ return this.salary;
+}
+
+// driver code
+const emp = new Employee(1);
+emp.setSalary(10000);
+console.log(emp.getSalary());
+```
+
+###### Notes
+Constructor function can be called without new keyword as well, which executes the function normally which is of not much use in most of the cases.
+
+###### References
+- https://javascript.info/constructor-new
+
+
+
+#### Q16
+### Show the procedure of creating object using a factory function
+
+- Any function which is not a class or constructor that returns an object without a new keyword is known as factory function
+- A normal function which can be modified to return an object which can be called by passing arguments
+
+```js
+function factoryFunc(username, password, isActive = false, isAdmin = false) {
+ if (typeof username !== 'string' && typeof password !== 'string') throw new Error('Invalid username or password');
+
+ return {
+ username,
+ password,
+ isActive,
+ isAdmin,
+ created: new Date(),
+ };
+}
+
+// driver code
+const user = factoryFunc('admin', 'password');
+```
+
+###### References
+- https://medium.com/javascript-scene/javascript-factory-functions-with-es6-4d224591a8b1
+
+
+
+#### Q17
+### Achieve prototypal inheritance using functions to create objects in JavaScript
+
+- 2 functions can be used create objects with constructor call to the functions
+- The prototype of child function is connected with parent function to achieve the inheritance behavior
+
+```js
+function parent(name){
+ this.name = name;
+}
+
+parent.prototype.getName = function (){
+ return this.name;
+}
+
+function child(name){
+ parent.call(this, name);
+}
+
+child.prototype = Object.create(parent.prototype);
+child.prototype.getMyName = function(){
+ return this.name;
+}
+
+// driver code
+var fk = new child("FK");
+console.log(fk.getName());
+console.log(fk.getMyName());
+
+var pk = new parent("PK");
+console.log(pk.getName());
+```
+
+###### Notes
+Solution is one of the known way of achieving prototypal inheritance, but is not the only way to achieve it.
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
+
+
+
+#### Q18
+### Write a code to show the differences between the techniques, currying and partial application
+
+- A function returning another function that might return another function, but every returned function must take only one parameter at a time is __currying__
+- A function returning another function that might return another function, but each returned function can take several parameters is __partial application__
+
+```js
+// currying
+function multiply(num1){
+ return function (num2){
+ return function (num3){
+ return num1 * num2 * num3;
+ }
+ }
+}
+```
+
+```js
+// partial application
+function multiply(num1){
+ return function (num2, num3){
+ return function (num4){
+ return num1 * num2 * num3 * num4;
+ }
+ }
+}
+```
+
+###### References
+- https://towardsdatascience.com/javascript-currying-vs-partial-application-4db5b2442be8
+- https://medium.com/better-programming/functional-programming-currying-vs-partial-application-53b8b05c73e3
+
+
+
+#### Q19
+### Write a function to copy functions of an object to another object (mixin)
+
+- Mixins are a form of object composition, where component features get mixed into a composite object
+- In JavaScript we can only inherit from a single object. Mixins allow copying properties of other function prototype or objects to the target object
+
+```js
+// mixin using Object.assign
+
+function mixin(sourceObj, targetObj) {
+ // copy properties of source object to target object
+ return Object.assign(targetObj, sourceObj);
+}
+
+// driver code
+const obj1 = {
+ task1() {
+ console.log('Task1');
+ },
+};
+
+const obj2 = {
+ task2() {
+ console.log('Task2');
+ },
+};
+
+let mixinObj = mixin(obj1, {});
+mixinObj = mixin(obj2, mixinObj);
+mixinObj.task1(); // Task1
+mixinObj.task2(); // Task2
+```
+
+```js
+// mixin using property copy through loops (pre ES6)
+
+function mixin(sourceObj, targetObj) {
+ for (var key in sourceObj) {
+ // only copy if not already present
+ if (!(key in targetObj)) {
+ targetObj[key] = sourceObj[key];
+ }
+ }
+ return targetObj;
+}
+
+// driver code
+var obj1 = {
+ task1() {
+ console.log('Task1');
+ },
+};
+
+var obj2 = {
+ task2() {
+ console.log('Task2');
+ },
+};
+
+var mixinObj = mixin(obj1, {});
+mixinObj = mixin(obj2, mixinObj);
+mixinObj.task1(); // Task1
+mixinObj.task2(); // Task2
+```
+
+###### Notes
+'task1' and 'task2' from 'obj1' and 'obj2' are copied to 'mixinObj'
+
+###### References
+- https://javascript.info/mixins
+
+
+
+#### Q20
+### Show the usage Proxy for function
+
+- The Proxy object enables create a proxy for a function, which can intercept the function calls
+- Proxy takes 1st argument as an function and 2nd argument as a object with different function traps
+
+```js
+const proxy = new Proxy(function () { console.log(arguments); }, {
+ apply(target, context, args){
+ console.log("Proxy apply is invoked on target with context: " + context + ", arguments: " + args);
+ return target.apply(context, args);
+ }
+});
+
+// driver code
+proxy(1, 2, 3); // Proxy apply is invoked on target with context: undefined, arguments: 1,2,3
+proxy.call({}, 1, 2); // Proxy apply is invoked on target with context: undefined, arguments: 1,2,3
+proxy.apply({}, [5, 10]); // Proxy apply is invoked on target with context: [object Object], arguments: 5,10
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
+
+
+
+[[↑] Back to top](#home)
diff --git a/challenges/functions.md b/challenges/functions.md
deleted file mode 100644
index 3a2ac17..0000000
--- a/challenges/functions.md
+++ /dev/null
@@ -1,1319 +0,0 @@
-
-
-## JavaScript interview code challenges on Functions
-
-1. [Write a function which returns another function and execute it after calling](#Q1)
-2. [Write a function which executes another function recieved as an argument](#Q2)
-3. [Create a function having no parameters declared and print all the arguments passed to it](#Q3)
-4. [Write a function which executes only if the number of arguments match the number of parameters the function is expecting](#Q4)
-5. [Design a function which can recieve variable number of arguments in parameters and print them](#Q5)
-6. [Show the most common ways of creating functions in JavaScript](#Q6)
-7. [Code the different forms of arrow functions for varying number of parameters](#Q7)
-8. [Write a program where hoisting can be visualized](#Q8)
-9. [Code an Immediately Invoked Function Expression (IIFE) and show the different ways of executing it](#Q9)
-10. [Create an IIFE which receives arguments and executes](#Q10)
-11. [Show the usage of IIFE to set a value of a variable](#Q11)
-12. [Design a Calulator interface for 2 number inputs which can perform sum, difference, product and dividend whenever invoked on the same interface](#Q12)
-13. [Write a function which can return multiple values from a function](#Q13)
-14. [Write a function which can set default value to the parameters of function when an argument is not passed. Also show how to use exisiting parameters to set the value of another parameter](#Q14)
-15. [Design a private counter function which exposes increment and retrive functionalities](#Q15)
-16. [Show the usage of call, apply and bind with practical example](#Q16)
-17. [Show the usage of function which can used as a constructor](#Q17)
-18. [Show the procedure of creating object using a factory function](#Q18)
-19. [Achieve prototypal inheritance using functions to create objects in JavaScript](#Q19)
-20. [Write a polyfill for bind function](#Q20)
-21. [Write a function which will create a function bounded to the context like `bind`, but can be overridden when the context is set explicitly](#Q21)
-22. [Write a function which helps to achieve multiply(a)(b) and returns product of a and b](#Q22)
-23. [Write a code to show the differences between the techniques, currying and partial application](#Q23)
-24. [Create a function which takes another function as an argument and makes it eligible for currying or partial application](#Q24)
-25. [Design a function which helps to do debouncing](#Q25)
-26. [Design a function which helps to do throttling](#Q26)
-27. [Design an interface which limits the number of function calls by executing the function once for a given count of calls](#Q27)
-28. [Write a singleton function to create an object only once](#Q28)
-29. [Design a function with toggle functionality for given list of inputs where toggle function accepts list of values to be toggled upon](#Q29)
-30. [Create a range function which returns an array for the provided inputs as start and end](#Q30)
-31. [Write a function which takes a function as an argument to achieve memoization](#Q31)
-32. [Write a function to copy functions of an object to another object (mixin)](#Q32)
-33. [Create a single function which can perform sum(a, b, c), sum(a, b)(c), sum(a)(b, c) and sum(a)(b)(c) and returns sum of a, b and c](#Q33)
-34. [Design a function which can keep recieving the arguments on each function call and returns the sum when no argument is passed](#Q34)
-35. [Show the usage Proxy for function](#Q35)
-36. [Create an interface for a function such that whenever a function is triggered the system should log the time. Do not modify the function code](#Q36)
-37. [Create an interface exposing subscribe and publish functionality, which allows publishing data which in turn invokes all the subscribers with the data](#Q37)
-
----
-
-#### Q1
-### Write a function which returns another function and execute it after calling
-
-- Functions can be declared, executed or returned inside another function
-
-```js
-function higherOrderFunction(){
- function displayHello(){
- console.log("Hello")
- }
- return displayHello;
-}
-
-// driver code
-var func = higherOrderFunction();
-func(); // hello
-```
-
-###### Notes
-Function can also be stored in variables like other values in JavaScript
-
-###### References
-- https://eloquentjavascript.net/05_higher_order.html
-- https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function
-
-
-
-#### Q2
-### Write a function which executes another function recieved as an argument
-- Functions can be passed as arguments to another functions
-- Passing the function as argument will pass its reference hence no parenthesis
-
-```js
-function callbackExecutor(callback){
- if(typeof callback === "function"){
- callback();
- }
-}
-
-
-// driver code
-function callbackFunc(){
- console.log("Callback function executed");
-}
-
-callbackExecutor(callbackFunc); // Callback function executed
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Glossary/Callback_function
-
-
-
-#### Q3
-### Create a function having no parameters declared and print all the arguments passed to it
-
-- When a function is invoked the arguments passed to it are accessible using the defualt object called "arguments"
-- Numbers starting from 0 is set as key of the object "arguments" corresponding to each argument in the order
-- `arguments` object will have length property as well which gives count of arguments passed
-
-```js
-function func(){
- for(let key in arguments){
- console.log(arguments[key]);
- }
-}
-
-// driver code
-func(1, "Hello", true);
-```
-
-```js
-function func(){
- for(let value of arguments){
- console.log(value);
- }
-}
-
-// driver code
-func(1, "Hello", true);
-```
-
-###### Notes
-Though the keys of arguments object look like numbers, "arguments" is not an array. Arrow functions will not have arguments object
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
-
-
-
-#### Q4
-### Write a function which executes only if the number of arguments match the number of parameters the function is expecting
-
-- The number of parameters declared in a function can be obtained by accessing the length property of the function
-
-```js
-function func(a, b, c){
- if(func.length === arguments.length){
- console.log("Number of arguments passed match the expected arguments");
- }
- else {
- throw new Error("Number of arguments passed do not match the expected arguments");
- }
-}
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length
-
-
-
-#### Q5
-### Design a function which can recieve variable number of arguments in parameters and print them
-
-```js
-function varArgsFunc(...params){
- params.forEach(function(value, index){
- console.log(index, ": ", value);
- })
-}
-
-// driver code
-varArgsFunc("Hello", ",", "World", "!!!");
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
-
-
-
-#### Q6
-### Show the most common ways of creating functions in JavaScript
-
-- The functions are most commonly created as function statements, function expression and arrow functions
-- Function statements get hoisted unlike function expressions
-
-```js
-// Regular function as a function statement
-function functionName(params) {
- //code block
-}
-```
-
-```js
-// Regular function as a function expression
-const functionName = function (params) {
- //code block
-}
-```
-
-```js
-// Arrow function as a function expression
-const arrowFunctionName = (params) => {
- //code block
-}
-```
-
-###### Notes
-As the arrow functions are not verbose, majority of developers prefer to create arrow functions for quick coding
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
-
-
-
-#### Q7
-### Code the different forms of arrow functions for varying number of parameters
-
-- Arrow functions provide simpler syntax over `function` keyword functions
-- Arrow functions with single parameter, round brackets are optional
-- Arrow functions with single statement with return, flower brackets and return keywords are optional
-
-```js
-const noArgsFunc = () => {
- return "No args passed"
-};
-```
-
-```js
-const singleArgFunc = (arg1) => "Argument is " + arg1;
-```
-
-```js
-const singleArgFunc = arg1 => {
- console.log("Argument is " + arg1);
- return arg1;
-};
-```
-
-```js
-const twoArgsFunc = (arg1, arg2) => {
- return arg1 + arg2;
-}
-```
-
-```js
-const threeArgsFunc = (arg1, arg2, arg3) => {
- console.log("Sum is " + (arg1 + arg2 + arg3));
- return true;
-}
-```
-
-###### Notes
-Arrow functions are also called fat arrow functions
-
-###### References
-- https://developer.mozilla.org/en-US/docs/web/JavaScript/Reference/Operators/function
-
-
-
-#### Q8
-### Write a program where hoisting can be visualized
-
-- The function statement and variable declared with `var` are accessible before it appears in the code
-- Declarations are put into memory before it executes any code segment that allows us to use a function before you declare it in your code
-- In hoisting the hoisted items are accessible in the scope it is declared
-- Function expressions do not get hoisted
-
-```js
-num1 = 10;
-printHello();
-
-var num1;
-function printHello(){
- console.log("Hello");
-}
-
-var nonHoistedFunc = function(){
- console.log("Hello");
-}
-```
-
-###### Notes
-Hoisting was thought up as a general way of thinking about how execution contexts work in JavaScript. In reality, code does not get hoisted, but affect is seen due to compilation and execution phases followed by JavaScript compiler
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
-
-
-
-#### Q9
-### Code an Immediately Invoked Function Expression (IIFE) and show the different ways of executing it
-
-- IIFE is a JavaScript function that runs as soon as it is defined
-- IIFE prevents polluting the global scope
-
-```js
-(function IIFE(){
- console.log("I am an Immediately invoked function");
-})();
-```
-
-```js
-(function IIFE(){
- console.log("I am an Immediately invoked function");
-}());
-```
-
-```js
-+function IIFE(){
- console.log("I am an Immediately invoked function");
-}();
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Glossary/IIFE
-
-
-
-#### Q10
-### Create an IIFE which receives arguments and executes
-
-- Arguments can be passed normally to an IIFE like we pass to while calling regular functions
-- Multiple arguments can be passed similar to function invokation with arguments
-
-```js
-(function IIFE(param1, param2){
- console.log("I am an Immediately invoked function");
- console.log("Parameter 1: " + param1);
- console.log("Parameter 2: " + typeof param2);
- console.log("Parameter 2 output: " + param2());
-})("hello", function(){ return "I am a string from a function passed to IIFE"; });
-```
-
-###### Notes
-A string and a function is passed as arguments to the IIFE
-
-
-
-#### Q11
-### Show the usage of IIFE to set a value of a variable
-
-- IIFE can be directly executed when it is used as an expression against assignment to a variable
-
-```js
-var randomNumber = function (){
- return Math.floor(Math.random() * 100);
-}();
-```
-
-
-
-#### Q12
-### Design a Calulator interface for 2 number inputs which can perform sum, difference, product and dividend whenever invoked on the same interface
-```js
-// Example
-const calc12And5 = Calculator(12, 5);
-calc12And5.sum(); // 17
-calc12And5.difference(); // 7
-calc12And5.product(); // 60
-calc12And5.dividend(); // 2
-```
-
-- Simple revealing module pattern can be used which receives inputs and executes different operations exposed through functions
-
-```js
-function Calulator(num1, num2){
-
- function sum(){
- return num1 + num2;
- }
-
- function difference(){
- return num1 - num2;
- }
-
- function product(){
- return num1 * num2;
- }
-
- function dividend(){
- return Math.floor(num1 / num2);
- }
-
- return { sum, difference, product, dividend };
-}
-```
-
-###### Notes
-The solution provided is one of the way to achieve the interface. The design and solution can vary
-
-###### References
-- https://eloquentjavascript.net/10_modules.html
-
-
-
-#### Q13
-### Write a function which can return multiple values from a function
-
-- Function in general is designed to return a single value.
-- Generators are special type of functions which returns iterator which in turn can be used to send & receive values.
-
-```js
-function multipleValueReturnFunc(){
- const a = 5, b = 10;
- return [a, b];
-}
-
-// driver code
-const [x, y] = multipleValueReturnFunc();
-```
-
-```js
-function multipleValueReturnFunc(){
- const a = 'Java', b = 'Script';
- return {
- a, b
- };
-}
-
-// driver code
-const {x, y} = multipleValueReturnFunc();
-```
-
-```js
-function* multipleValueReturnFunc(){
- const a = 5, b = 10;
- yield a;
- yield b;
-}
-
-// driver code
-const iterator = multipleValueReturnFunc();
-const x = iterator.next().value;
-const y = iterator.next().value;
-```
-
-###### Notes
-Array and object are used in the programs to contain multiple values
-
-
-
-#### Q14
-### Write a function which can set default value to the parameters of function when an argument is not passed. Also show how to use exisiting parameters to set the value of another parameter
-
-- Default function parameters allow named parameters to be initialized with default values if no value or undefined is passed
-
-```js
-function defaultValueFunc(num = 10, num2 = 20, string = "Hello", bool = false, sum = num1 + num2 ){
- console.log(num, string, bool, sum);
-}
-
-// driver code
-defaultValueFunc(); // 10, 20, false, 30
-defaultValueFunc(4, 8); // 4, 8, false, 12
-defaultValueFunc(10, 4, true); // 10, 4, true, 14
-defaultValueFunc(5, 6, false, 11); // 5, 6, false, 11
-defaultValueFunc(undefined, undefined, false); // 10, 20, false, 30
-```
-
-###### Notes
-The default values are set only for missing or `undefined`. `null` and other falsy values are considered as valid arguments and default will not be set
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
-
-
-
-#### Q15
-### Design a private counter function which exposes increment and retrive functionalities
-
-```js
-function privateCounter(){
- var count = 0;
- return {
- increment: function(val = 1){
- count += val;
- }
- retrieve: function(){
- return count;
- }
- }
-}
-
-// driver code
-const counter = privateCounter();
-counter.increment();
-counter.increment();
-counter.retrieve(); // 2
-counter.increment(5);
-counter.increment();
-counter.retrieve(); // 8
-```
-
-###### Notes
-'increment' function takes an argument to increment if passed else which is set to 1 (increments by 1)
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
-
-
-
-#### Q16
-### Show the usage of call, apply and bind with practical example
-
-- 'call' is a method on function prototype and is used to set the context of the function by passing it as 1st argument followed by the arguments
-- 'apply' is a method on function prototype and is used to set the context of the function by passing it as 1st argument followed by the array of arguments
-- 'bind' is a method on function prototype and is used to create a new function with the context as the 1st argument followed by the arguments
-
-```js
-function displayThisValue(param1, param2) {
- console.log(this.value, param1, param2);
-}
-
-const obj = {
- value: 10
-}
-const valueArr = [20, 30];
-
-// No context set
-displayThisValue(20, 30); // undefined, 20, 30
-
-// 'obj' is set as the context using 'call'
-displayThisValue.call(obj, ...valueArr); // 10, 20, 30
-
-// 'obj' is set as the context using 'apply'
-displayThisValue.apply(obj, valueArr); // 10, 20, 30
-
-// No context set
-setTimeout(displayThisValue, 1000, ...valueArr); // undefined, 20, 30
-
-// 'obj' is set as the context using 'bind'
-setTimeout(displayThisValue.bind(obj), 1000, ...valueArr); // 10, 20, 30
-setTimeout(displayThisValue.bind(obj, ...valueArr), 1000); // 10, 20, 30
-```
-
-###### Notes
-The context inside the function can be accessed using `this` keyword
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
-- https://javascript.info/bind
-
-
-
-#### Q17
-### Show the usage of function which can used as a constructor
-
-- Function can be used to like a constructor by calling it with a `new` keyword
-- Constructor function is a normal function but generally used to create object and may also have functions in its prototype
-- Constructor function is generally preferred to start with Uppercase letter which is not mandatory
-- The return from the constructor function is new object created which is accessed with `this` inside the function
-- Constructor function can return an explicit object as well
-
-```js
-function Employee(id){
- this.id = id;
-}
-
-Employee.prototype.setSalary = function(salary){
- this.salary = salary;
-}
-
-Employee.prototype.getSalary = function(){
- return this.salary;
-}
-
-// driver code
-const emp = new Employee(1);
-emp.setSalary(10000);
-console.log(emp.getSalary());
-```
-
-###### Notes
-Constructor function can be called without new keyword as well, which executes the function normally which is of not much use in most of the cases.
-
-###### References
-- https://javascript.info/constructor-new
-
-
-
-#### Q18
-### Show the procedure of creating object using a factory function
-
-- Any function which is not a class or constructor that returns an object without a new keyword is known as factory function
-- A normal function which can be modified to return an object which can be called by passing arguments
-
-```js
-function factoryFunc(username, password, isActive = false, isAdmin = false) {
- if (typeof username !== 'string' && typeof password !== 'string') throw new Error('Invalid username or password');
-
- return {
- username,
- password,
- isActive,
- isAdmin,
- created: new Date(),
- };
-}
-
-// driver code
-const user = factoryFunc('admin', 'password');
-```
-
-###### References
-- https://medium.com/javascript-scene/javascript-factory-functions-with-es6-4d224591a8b1
-
-
-
-#### Q19
-### Achieve prototypal inheritance using functions to create objects in JavaScript
-
-- 2 functions can be used create objects with constructor call to the functions
-- The prototype of child function is connected with parent function to achieve the inheritance behavior
-
-```js
-function parent(name){
- this.name = name;
-}
-
-parent.prototype.getName = function (){
- return this.name;
-}
-
-function child(name){
- parent.call(this, name);
-}
-
-child.prototype = Object.create(parent.prototype);
-child.prototype.getMyName = function(){
- return this.name;
-}
-
-// driver code
-var fk = new child("FK");
-console.log(fk.getName());
-console.log(fk.getMyName());
-
-var pk = new parent("PK");
-console.log(pk.getName());
-```
-
-###### Notes
-Solution is one of the known way of achieving prototypal inheritance, but is not the only way to achieve it.
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
-
-
-
-#### Q20
-### Write a polyfill for bind function
-
-- The `bind` method creates a new function that, when called, has its this keyword set to the provided context
-
-```js
-if(!Function.prototype.bind){
- Function.prototype.bind = function(context){
- var fn = this;
- var fnArgs = Array.prototype.slice.call(arguments, 1);
-
- return function(){
- var allArgs = funcArgs.concat(Array.prototype.slice.call(arguments))
- fn.apply(context, allArgs);
- };
- }
-}
-```
-
-###### Notes
-This is a simple polyfill for bind without handling corner cases. It does not work when using the new operator
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
-
-
-
-#### Q21
-### Write a function which will create a function bounded to the context like `bind`, but can be overridden when the context is set explicitly
-
-- The functionality is similar to `bind` with exception that if there is a context set during the execution it will override
-
-```js
-function softBind(fn, context) {
- var fnArgs = Array.prototype.slice.call(arguments, 2);
-
- return function() {
- var allArgs = fnArgs.concat(Array.prototype.slice.call(arguments));
-
- // override the context to incoming context if it is not undefined, null or window
- var context = (!this || this === window) ? obj : this;
- fn.apply(context, allArgs);
- };
-}
-```
-
-###### Notes
-This functionality is also known as 'Soft Binding'
-
-###### References
-- https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch2.md#softening-binding
-- https://gist.github.com/getify/9043478
-
-
-
-#### Q22
-### Write a function which helps to achieve multiply(a)(b) and returns product of a and b
-```js
-// Example
-multiply(2)(4); // 8
-multiply(5)(3); // 15
-```
-
-- The implementation of this can be achieved by calling a function which returns a function
-
-```js
-function multiply(num1){
- return function (num2){
- return num1 * num2;
- }
-}
-```
-
-###### References
-- https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983
-
-
-
-#### Q23
-### Write a code to show the differences between the techniques, currying and partial application
-
-- A function returning another function that might return another function, but every returned function must take only one parameter at a time is __currying__
-- A function returning another function that might return another function, but each returned function can take several parameters is __partial application__
-
-```js
-// currying
-function multiply(num1){
- return function (num2){
- return function (num3){
- return num1 * num2 * num3;
- }
- }
-}
-```
-
-```js
-// partial application
-function multiply(num1){
- return function (num2, num3){
- return function (num4){
- return num1 * num2 * num3 * num4;
- }
- }
-}
-```
-
-###### References
-- https://towardsdatascience.com/javascript-currying-vs-partial-application-4db5b2442be8
-- https://medium.com/better-programming/functional-programming-currying-vs-partial-application-53b8b05c73e3
-
-
-
-#### Q24
-### Create a function which takes another function as an argument and makes it eligible for currying or partial application
-
-- Function can take another function as argument and accept the arguments on the returned functions till the expected arguments are reached
-- The arguments can be 1 or multiple, and the actual function will be called once the count of expected arguments are reached
-
-```js
-function curryFunc(fn) {
- return function curry(...args) {
- if (fn.length <= args.length) {
- return fn.apply(this, args);
- } else {
- return function (...args2) {
- return curry.apply(this, args.concat(args2));
- };
- }
- };
-}
-
-// driver code
-let sum = curryFunc(function (a, b, c, d) {
- return a + b + c + d;
-});
-
-sum(1)(2)(3)(4); // called like curried function
-sum(1,2)(3,4); // called like partial application
-```
-
-###### References
-- https://javascript.info/currying-partials#advanced-curry-implementation
-
-
-
-#### Q25
-### Design a function which helps to do debouncing
-
-- The `debounce` function forces a function to wait a certain amount of time before running again
-- The function is built to limit the number of function calls to improve the performance
-- Debounce function design can take function (to be debounced), delay and the optional context
-
-```js
-function debounce(fn, delay, context){
- let timer;
-
- return function(...args){
- if(timer) clearTimeout(timer);
-
- context = this ?? context;
- timer = setTimeout(()=>{
- fn.apply(context, args);
- }
- , delay);
- }
-}
-```
-
-###### Notes
-Context is replaced while debounce function call in presence of a context. If not, context set during the `debounce` function call is used.
-
-###### References
-- https://www.youtube.com/watch?v=Zo-6_qx8uxg
-
-
-
-#### Q26
-### Design a function which helps to do throttling
-
-- The `throttling` function forces a function to run once in an amount of time for one or multiple calls
-- The function is built to limit the number of function calls to improve the performance
-- Throttling function design can take function (to be throttled), delay and the optional context
-
-```js
-function throttle(fn, delay, context){
- let timer;
- let lastArgs;
-
- return function(...args){
- lastArgs = args;
- context = this ?? context;
-
- if(timer) return;
-
- timer = setTimeout(()=>{
- fn.apply(context, lastArgs);
- clearTimeout(timer);
- }
- , delay);
- };
-}
-```
-
-###### Notes
-Last arguments to the throttled function is saved so that most recent arguments will be used for throttled function execution (unlike debouncing where it is taken care due to its way of execution)
-
-###### References
-- https://www.youtube.com/watch?v=81NGEXAaa3Y
-
-
-
-#### Q27
-### Design an interface which limits the number of function calls by executing the function once for a given count of calls
-
-- function forces a function run to for specific number of times in a given number of execution calls
-- The function is built to limit the number of times a function is called
-- Throttling function design can take function (to be throttled), delay and the optional context
-
-```js
-function sampler(fn, count, context){
- let counter = 0;
-
- return function(...args){
- lastArgs = args;
- context = this ?? context;
-
- if(++counter !== count) return;
-
- fn.apply(context, args);
- counter = 0;
- };
-}
-```
-
-###### Notes
-Sampling is different from throttling in the way that sampling limits the execution by executing function once in a given number of calls where as throttling limits the execution by executing function once in a given amount of time
-
-###### References
-- https://rxjs.dev/api/operators/sample
-
-
-
-#### Q28
-### Write a singleton function to create an object only once
-
-- Singleton is a design pattern which restricts the creation of only one object from a given interface
-- When requested multiple times, same object is returned
-
-```js
-var Singleton = (function () {
- var instance;
-
- function createInstance() {
- var object = new Object("I am the instance");
- return object;
- }
-
- return {
- getInstance: function () {
- if (!instance) {
- instance = createInstance();
- }
- return instance;
- }
- };
-})();
-
-// driver code
-const instance1 = Singleton.getInstance();
-const instance2 = Singleton.getInstance();
-```
-
-###### Notes
-Here both 'instance1' and 'instace2' are referencing to the same object
-
-###### References
-- https://www.dofactory.com/javascript/design-patterns/singleton
-
-
-
-#### Q29
-### Design a function with toggle functionality for given list of inputs where toggle function accepts list of values to be toggled upon
-```js
-// Example
-var hello = toggle("hello");
-var onOff = toggle("on","off");
-var speed = toggle("slow","medium","fast");
-
-hello(); // "hello"
-hello(); // "hello"
-
-onOff(); // "on"
-onOff(); // "off"
-onOff(); // "on"
-
-speed(); // "slow"
-speed(); // "medium"
-speed(); // "fast"
-speed(); // "slow"
-```
-
-- Toggle functionality can be obtained by returning the next value cyclically on each call to the function
-- The toggle function will return another function which maintains the closure over the values with which it was initialized
-
-```js
-function toggle(...values){
- let state = -1;
- const length = values.length;
- return function(){
- state = (state + 1) % length;
- return values[state];
- }
-}
-```
-
-###### References
-- https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/apB.md#closure-part-2
-
-
-
-#### Q30
-### Create a range function which returns an array for the provided inputs as start and end
-```js
-// Example
-range(3, 6) // [3, 4, 5, 6]
-range(3)(5) // [3, 4, 5]
-range(3)(0) // []
-```
-
-- Range functionality can be obtained by returning the an array from start to end both inclusive
-- In case if 2nd argument is not passed, function will return another function which calls itself with once both the values are obtained
-
-```js
-function range(start, end) {
- if (end === undefined) {
- return function (end) {
- return range(start, end);
- };
- }
-
- const arr = [];
- for (let i = start; i <= end; i++) {
- arr.push(i);
- }
- return arr;
-}
-```
-
-###### References
-- https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/get-started/apB.md#appendix-b-practice-practice-practice
-
-
-
-#### Q31
-### Write a function which takes a function as an argument to achieve memoization
-
-- Memoization is an optimization technique used primarily to speed up the programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again
-- Function can be designed to use a cache storage (using `map` or `object`) which stores the values of function output against the input
-
-```js
-function memoize(fn) {
- const cache = new Map();
- return function () {
- const key = JSON.stringify(arguments);
-
- // if the caculations have already been done for inputs, return the value from cache
- if (cache.has(key)) {
- return cache.get(key);
- } else {
- // call the function with arguments and store the result in cache before returning
- cache.set(key, fn(...arguments));
- return cache.get(key);
- }
- };
-}
-
-// driver code
-let factorial = memoize(function fact(value) {
- return value > 1 ? value * fact(value - 1) : 1;
-});
-
-factorial(5); // 120 (output is calculated by calling the function)
-factorial(5); // 120 (output is returned from the cache which was stored from previous calculations)
-```
-
-###### Notes
-Stringification of arguments done in order for the function to work for multiple arguments
-
-###### References
-- https://codeburst.io/understanding-memoization-in-3-minutes-2e58daf33a19
-
-
-
-#### Q32
-### Write a function to copy functions of an object to another object (mixin)
-
-- Mixins are a form of object composition, where component features get mixed into a composite object
-- In JavaScript we can only inherit from a single object. Mixins allow copying properties of other function prototype or objects to the target object
-
-```js
-// mixin using Object.assign
-
-function mixin(sourceObj, targetObj) {
- // copy properties of source object to target object
- return Object.assign(targetObj, sourceObj);
-}
-
-// driver code
-const obj1 = {
- task1() {
- console.log('Task1');
- },
-};
-
-const obj2 = {
- task2() {
- console.log('Task2');
- },
-};
-
-let mixinObj = mixin(obj1, {});
-mixinObj = mixin(obj2, mixinObj);
-mixinObj.task1(); // Task1
-mixinObj.task2(); // Task2
-```
-
-```js
-// mixin using property copy through loops (pre ES6)
-
-function mixin(sourceObj, targetObj) {
- for (var key in sourceObj) {
- // only copy if not already present
- if (!(key in targetObj)) {
- targetObj[key] = sourceObj[key];
- }
- }
- return targetObj;
-}
-
-// driver code
-var obj1 = {
- task1() {
- console.log('Task1');
- },
-};
-
-var obj2 = {
- task2() {
- console.log('Task2');
- },
-};
-
-var mixinObj = mixin(obj1, {});
-mixinObj = mixin(obj2, mixinObj);
-mixinObj.task1(); // Task1
-mixinObj.task2(); // Task2
-```
-
-###### Notes
-'task1' and 'task2' from 'obj1' and 'obj2' are copied to 'mixinObj'
-
-###### References
-- https://javascript.info/mixins
-
-
-
-#### Q33
-### Create a single function which can perform sum(a, b, c), sum(a, b)(c), sum(a)(b, c) and sum(a)(b)(c) and returns sum of a, b and c
-```js
-// Example
-sum(2)(4)(6); // 12
-sum(3, 2)(5); // 10
-sum(4)(-10, -6); // -12
-sum(6, -3, 1); // 4
-```
-
-- Sum functionality can be obtained by returning the sum when all the arguments are present
-- The cases when only 1 or 2 arguments are passed need to be managed and handled
-
-```js
-function sum(a, b, c){
- if(a !== undefined && b !== undefined && c !== undefined){
- return a + b + c;
- }
- if(a !== undefined && b !== undefined){
- return function(c){
- return sum(a, b, c);
- }
- }
- return function(b, c){
- if(b !== undefined && c !== undefined){
- return sum(a, b, c);
- }
- return function(c){
- return sum(a, b, c);
- }
- }
-}
-```
-
-```js
-const countOfValues = 3;
-
-function sum() {
- const args = arguments;
-
- if (args.length === countOfValues) {
- return Array.prototype.reduce.call(args, (a, b) => a + b);
- }
-
- return function () {
- return sum(...args, ...arguments);
- };
-}
-```
-
-###### Notes
-2nd approach is generic technique and can be used customized for any number of values
-
-
-
-#### Q34
-### Design a function which can keep recieving the arguments on each function call and returns the sum when no argument is passed
-
-- The function can be designed to return another function which maintains the closure over the previous sum value
-- The check for breaking condition can be added using the argument check for `undefined`
-- 3rd solution uses the property on function to store the total which will be updated on each call hence the same function can be returned
-
-```js
-// Example
-sum(2)(4)(6)(1)(); // 13
-sum(2)(4)(); // 6
-sum(3)(); // 3
-```
-
-- Sum functionality can be obtained by returning the recursively calling till the 2nd parameter value is undefined
-
-```js
-function sum(a) {
- return function (b) {
- if (b === undefined) {
- return a;
- }
- return sum(a + b);
- };
-}
-```
-
-```js
-const sum = a => b => b === undefined ? a : sum(a + b);
-```
-
-```js
-function sum(a) {
- if (typeof a === 'undefined') {
- return sum.total;
- }
- sum.total = (sum.total ?? 0) + a;
- return sum;
-}
-```
-
-###### Notes
-In the code value is checked if it is undefined reason being 0 is a falsy value and `b ? a : sum(a + b)` code fails when one of the argument is 0. Example: `sum(4)(3)(0)(2)()`
-
-###### References
-- https://www.youtube.com/watch?v=D5ENjfSkHY4
-
-
-
-#### Q35
-### Show the usage Proxy for function
-
-- The Proxy object enables create a proxy for a function, which can intercept the function calls
-- Proxy takes 1st argument as an function and 2nd argument as a object with different function traps
-
-```js
-const proxy = new Proxy(function () { console.log(arguments); }, {
- apply(target, context, args){
- console.log("Proxy apply is invoked on target with context: " + context + ", arguments: " + args);
- return target.apply(context, args);
- }
-});
-
-// driver code
-proxy(1, 2, 3); // Proxy apply is invoked on target with context: undefined, arguments: 1,2,3
-proxy.call({}, 1, 2); // Proxy apply is invoked on target with context: undefined, arguments: 1,2,3
-proxy.apply({}, [5, 10]); // Proxy apply is invoked on target with context: [object Object], arguments: 5,10
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
-
-
-
-#### Q36
-### Create an interface for a function such that whenever a function is triggered the system should log the time. Do not modify the function code
-
-- Function call can be handled using Proxy in JavaScript
-- `apply` keyword in proxy can be used to achieve the functionality without modifying the existing function code
-
-```js
-function generateSecretObject(key, value) {
- return { [key]: value };
-}
-
-generateSecretObject = new Proxy(generateSecretObject, {
- apply(target, context, args) {
- console.log(`${target.name} function is accessed at ${new Date()}`);
- return target.apply(context, args);
- },
-});
-
-// driver code
-const user = {
- username: "0001",
- generateSecretObject
-};
-generateSecretObject("username", "Password"); // "generateSecretObject function is accessed at {time}"
-```
-
-###### Notes
-This technique is helpful in logging or managing the data being passed to & returned from function without modifying the actual function code especially when function is a part of library or framework
-
-
-
-#### Q37
-### Create an interface exposing subscribe and publish functionality, which allows publishing data which in turn invokes all the subscribers with the data
-
-- A simple module with publish and subscribe function can be exposed to achieve such functionality
-- List of subscribers can be maintained in an array and can be invoked in loop on each publish
-
-```js
-function pubSub() {
- const subscribers = [];
-
- function publish(data) {
- subscribers.forEach(subscriber => subscriber(data));
- }
-
- function subscribe(fn) {
- subscribers.push(fn);
- }
-
- return {
- publish,
- subscribe,
- };
-}
-
-// driver code
-const pubSubObj = pubSub();
-pubSubObj.subscribe(data => {
- console.log('Subscriber 1: ' + data);
-});
-pubSubObj.subscribe(data => {
- console.log('Subscriber 2: ' + data);
-});
-
-// all subscribers will be called with the data on publish
-pubSubObj.publish('Value is 10');
-```
-
-###### Notes
-This is a well known JavaScript pattern called as __Publish/Subscribe Pattern__
-
-###### References
-- https://jsmanifest.com/the-publish-subscribe-pattern-in-javascript/
-
-
-
-[[↑] Back to top](#home)
diff --git a/challenges/objects-challenges.md b/challenges/objects-challenges.md
new file mode 100644
index 0000000..6f358c9
--- /dev/null
+++ b/challenges/objects-challenges.md
@@ -0,0 +1,721 @@
+
+
+## JavaScript interview code challenges on Objects - challenges
+
+1. [Display all the keys and values of a nested object](#Q1)
+1. [Write a program which can empty a given object](#Q2)
+1. [Show how a deep copy of an object can be done](#Q3)
+1. [Create an array of pair of values (key, value) from an object and store it in a map. Consider the object is not nested](#Q4)
+1. [Create an object with a property 'marks' which cannot be set to a value less than 0](#Q5)
+1. [Create an object which has a property 'userid' which can only be set once and will be a read only property](#Q6)
+1. [Design a function which takes an array as input and returns a function 'next', calling which fetches a value one by one](#Q7)
+1. [Create an object 'obj' with functions assigned to keys. Show how can we achieve 'obj.func1().func2().func3()' considering func1, func2, func3 are object keys](#Q8)
+1. [Create an object with property counter which keeps incrementing on every access](#Q9)
+1. [Create an object and make it behave like an array which allows push and pop operations on items](#Q10)
+1. [Write a function which can be used to deeply compare 2 nested objects](#Q11)
+1. [Design a class for employee which takes id and name in during construction of object and has a salary property](#Q12)
+1. [Write a program to make all the properties of an object ready only but allow the addition of new properties](#Q13)
+1. [Write a program which can return a boolean if value is present in the range with given start and end values in an object](#Q14)
+1. [Write a function which accepts a topic and a list of related tags to store the information. The same function should return all the topics when requested with a tagname](#Q15)
+1. [Write a function which accepts a collection of values & an iteratee as arguments and returns a grouped object](#Q16)
+1. [Create a constructor function which allows its functions present on prototype to be accessed only by the objects created by calling it](#Q17)
+1. [Design a utility on an array of objects where the access can be made to the object using index (as usual) and also from primary key of the object](#Q18)
+1. [Write a function which receives an object and returns a true if the object has circular reference](#Q19)
+1. [Write a code which can eliminate circular references in an object (Cyclic reference in an object)](#Q20)
+1. [Provide an object on which a value can be set to nested property even if it does not exist](#Q21)
+
+---
+
+#### Q1
+### Display all the keys and values of a nested object
+
+- `typeof` operator on value gives the type of value
+- Recursive solution can be used to iterate over all the nested objects
+
+```js
+function keyValuePrinter(obj){
+ for(let key in obj){
+ if(typeof obj[key] !== "object"){
+ console.log("[" + key + " : " + obj[key] + "]");
+ }
+ else{
+ keyValuePrinter(obj[key]);
+ }
+ }
+}
+```
+
+
+
+#### Q2
+### Write a program which can empty a given object
+
+- Object can be emptied by removing all the keys present on it
+- Alternatively, a new object can be created and the prototype of the new object can be set as prototype of old object
+
+```js
+for(let key in obj){
+ if(obj.hasOwnProperty(key)){
+ delete obj[key];
+ }
+}
+```
+
+```js
+const newObj = {};
+Object.setPrototypeOf(newObj, obj);
+```
+
+###### Notes
+'obj' is considered to be the object to be emptied
+
+
+
+#### Q3
+### Show how a deep copy of an object can be done
+
+- Deep copy is done by copying all the properties of the object to another object
+
+```js
+const x = Object.assign({}, obj);
+```
+
+```js
+const x = { ...obj};
+```
+
+```js
+const x = JSON.parse(JSON.stringify(obj));
+```
+
+###### Notes
+3rd solution provided does deep copy of a nested object also but this technique results in loss of data
+
+###### References
+- https://www.digitalocean.com/community/tutorials/copying-objects-in-javascript
+
+
+
+#### Q4
+### Create an array of pair of values (key, value) from an object and store it in a map. Consider the object is not nested
+
+- As the object is not nested, the key-value pairs can be obtained directly by using Object.entries
+- Map can be initialized with key-value pairs
+
+```js
+const map = new Map(Object.entries(obj));
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
+
+
+
+#### Q5
+### Create an object with a property 'marks' which cannot be set to a value less than 0
+
+- `getter` and `setter` on the properties of object can be used to control the read and write behavior
+
+```js
+const obj = { marks: 0 };
+
+Object.defineProperty(obj, 'marks', {
+ set(value) {
+ if(value < 0)
+ throw new Error("Marks cant be less than zero");
+ marks = value;
+ },
+ get() {
+ return marks;
+ }
+});
+```
+
+```js
+const obj = {
+ _marks: 0,
+
+ set marks(value){
+ if(value < 0)
+ throw new Error("Marks cant be less than zero");
+ this._marks = value;
+ },
+
+ get marks(){
+ return this._marks;
+ }
+}
+```
+
+###### Notes
+2nd solution shown directly defines `getter` and `setter` for property marks, hence uses another variable to store the data
+
+###### References
+- https://javascript.info/property-accessors
+
+
+
+#### Q6
+### Create an object which has a property 'userid' which can only be set once and will be a read only property
+
+- Property accessor `writable` to true sets the property to be read only
+
+```js
+function userObjectCreator(id){
+ const obj = { };
+
+ Object.defineProperty(obj, 'userid', {
+ value: id,
+ writable: false
+ });
+
+ return obj;
+}
+
+const obj = userObjectCreator(1);
+```
+
+###### Notes
+`obj.id` is a ready only property and does not allow overwriting
+
+
+
+#### Q7
+### Design a function which takes an array as input and returns a function 'next', calling which fetches a value one by one
+
+- The function returned `next` will return an object which contains value and done properties
+
+```js
+function makeIterator(array) {
+ let nextIndex = 0;
+ return {
+ next: function () {
+ return nextIndex < array.length
+ ? {
+ value: array[nextIndex++],
+ done: false,
+ }
+ : {
+ done: true,
+ };
+ },
+ };
+}
+
+// driver code
+let it = makeIterator(['yo', 'ya']);
+it.next().value; // 'yo'
+it.next().value; // 'ya'
+it.next().done; // true
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
+
+
+
+#### Q8
+### Create an object 'obj' with functions assigned to keys. Show how can we achieve 'obj.func1().func2().func3()' considering func1, func2, func3 are object keys
+
+- For achieving chaining functionality, each function can return the calling context itself so that context is retained
+
+```js
+var obj = {
+ id: 1,
+ username: "Jane",
+ dept: "Computers",
+
+ displayId(){
+ console.log("Id: " + this.id);
+ return this;
+ },
+
+ displayName(){
+ console.log("Name: " + this.username);
+ return this;
+ },
+
+ displayDept(dept){
+ if(typeof dept !== "undefined"){
+ this.dept = dept;
+ }
+ console.log("Dept: " + this.dept);
+ return this;
+ }
+}
+
+// driver code
+obj.displayId().displayName().displayDept("Info Tech");
+```
+
+###### Notes
+Order of calling the functions does not matter as all the functions are returning object itself
+
+###### References
+- https://medium.com/technofunnel/javascript-function-chaining-8b2fbef76f7f
+
+
+
+#### Q9
+### Create an object with property counter which keeps incrementing on every access
+```js
+const obj = counterObject();
+obj.counter; // 1
+obj.counter; // 2
+obj.counter; // 3
+```
+
+- The access to the property of the object can be configured through property `getter`
+- A separate private variable can be maintained track the value and getter on each access to increment and return the value
+
+```js
+function counterObject() {
+ const symCounter = Symbol('counter');
+
+ const obj = {
+ [symCounter]: 0,
+
+ get counter() {
+ return ++this[symCounter];
+ },
+
+ set counter(value) {
+ throw new Error('Cannot set the counter');
+ },
+ };
+ return obj;
+}
+```
+
+###### Notes
+Symbol is used to maintain the private variable in the object. Using the private variable to store the data such as `_counter` is also a well known pattern before symbols
+
+
+
+#### Q10
+### Create an object and make it behave like an array which allows push and pop operations on items
+
+- Object does not have by default a property named 'length' and hence we can define it on object which helps to track the length
+- 'push' and 'pop' functions can be added to the object which internally calls the Array methods `push` and `pop` by passing the object context
+
+```js
+const arrayLikeObject = {
+ length: 0,
+ push: function (item) {
+ Array.prototype.push.call(this, item);
+ },
+ pop: function () {
+ Array.prototype.pop.call(this);
+ }
+};
+
+// driver code
+arrayLikeObject.push('first');
+arrayLikeObject.push('second');
+arrayLikeObject.pop();
+arrayLikeObject; // { length: 1, 0: first }
+```
+
+###### Notes
+As the context for array methods is set object, length of the object changes whenever `push` and `pop` operations take place
+
+
+
+#### Q11
+### Write a function which can be used to deeply compare 2 nested objects
+```js
+// Example
+const obj1 = {
+ name: 'John',
+ details: {
+ x: 1,
+ y: 2,
+ },
+};
+
+const obj2 = {
+ name: 'John',
+ details: {
+ y: 2,
+ x: 1,
+ },
+};
+
+deepEqual(obj1, obj2); // true
+```
+
+- The objects can be deeply compared by checking the key value pairs recursively
+
+```js
+function deepEqual(object1, object2) {
+ const keys1 = Object.keys(object1);
+ const keys2 = Object.keys(object2);
+
+ if (keys1.length !== keys2.length) {
+ return false;
+ }
+
+ for (const key of keys1) {
+ const val1 = object1[key];
+ const val2 = object2[key];
+ const areObjects = val1 != null && typeof val1 === 'object' && val1 != null && typeof val2 === 'object';
+ if ((areObjects && !deepEqual(val1, val2)) || (!areObjects && val1 !== val2)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+```
+
+###### Notes
+Stringification of both objects and comparision will also work, but fails on keys order mismatch
+
+###### References
+- https://dmitripavlutin.com/how-to-compare-objects-in-javascript/
+
+
+
+#### Q12
+### Design a class for employee which takes id and name in during construction of object and has a salary property
+
+- Classes are a template for creating objects. They encapsulate data with code to work on that data
+- The constructor method is a special method for creating and initializing an object created with a class
+- Objects of the class can be created using `new` keyword followed by classname
+
+```js
+class Employee {
+ constructor(id, name) {
+ if (typeof id !== 'undefined' && typeof name !== 'undefined') {
+ this.id = id;
+ this.name = name;
+ } else
+ throw new Error('Employee id and name are mandatory for new employee creation');
+ }
+
+ getId() {
+ return this.id;
+ }
+
+ getName() {
+ return this.name;
+ }
+
+ setSalary(base, variable) {
+ this.salary = base + variable;
+ }
+
+ getSalary() {
+ return this.salary;
+ }
+}
+
+// driver code
+const emp = new Employee(1, "John Doe");
+emp.setSalary(10000, 1000);
+emp.getSalary(); // 11000
+```
+
+###### Notes
+Class in JavaScript is functionality to achieve class based model on top of prototype based programming model of JavaScript
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
+
+
+
+#### Q13
+### Write a program to make all the properties of an object ready only but allow the addition of new properties
+
+- The exisiting properties of the object can be made read only with `set` keyword using Proxy
+
+```js
+const readOnlyObj = new Proxy(obj, {
+ get: function (target, key) {
+ return target[key];
+ },
+
+ set: function() {
+ if(target.hasOwnProperty(key)){
+ throw new Error("Object properties are read only");
+ }
+ target[key] = value;
+ }
+});
+```
+
+###### Notes
+If condition takes care whether the property is new or existing to handle the read only scenario
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
+
+
+
+#### Q14
+### Write a program which can return a boolean if value is present in the range with given start and end values in an object
+```js
+// Example
+let range = {
+ start: 10,
+ end: 50
+};
+
+5 in range; // false
+25 in range; // true
+```
+
+- The object `in` can be trapped using Proxy trap `has`, to check if the value is in the range or not
+
+```js
+range = new Proxy(range, {
+ has(target, value){
+ return value >= target.start && value <= target.end;
+ }
+});
+```
+
+
+
+#### Q15
+### Write a function which accepts a topic and a list of related tags to store the information. The same function should return all the topics when requested with a tagname
+```js
+// Example
+const tagManager = TagManager();
+tagManager.addTags('React', 'Redux, JSX, JavaScript, VDOM');
+tagManager.addTags('Angular', 'RxJS, TypeScript, JavaScript');
+tagManager.addTags('Vue', 'VDOM, JavaScript');
+
+tagManager.getTopics.getTopics('VDOM'); // React, Vue
+tagManager.getTopics.getTopics('JavaScript'); // React, Angular, Vue
+```
+
+- The tags can be stored as keys and array of topics as values in a map
+- Function module can be desgined to expose 'addTags' and 'getTopics' by tagname
+
+```js
+function TagManager() {
+ const map = new Map();
+
+ function addTags(topic, tagText) {
+ const tagsArr = tagText.split(',').map(tag => tag.trim());
+
+ tagsArr.forEach(tag => {
+ if (map.has(tag)) {
+ map.get(tag).push(topic);
+ } else {
+ map.set(tag, [topic]);
+ }
+ });
+ }
+
+ function getTopics(tag) {
+ return map.get(tag);
+ }
+
+ return {
+ addTags,
+ getTopics
+ }
+}
+```
+
+
+
+#### Q16
+### Write a function which accepts a collection of values & an iteratee as arguments and returns a grouped object
+```js
+// Example
+groupBy([6.1, 4.2, 6.3], Math.floor); // { 6: [6.1, 6.3], 4: [4.2] }
+groupBy(['one', 'two', 'three'], 'length'); // { 3: ['one', 'two'], 5: ['three'] }
+```
+
+- As the 2nd argument is either a functin or property, the iteratee can be perfrom accordingly on the value of arrays
+- An empty object can be created and used to push the values of array to respective property of the iteratee output
+
+```js
+function groupBy(values, iteratee) {
+ const obj = {};
+ for (let value of values) {
+ const prop = typeof iteratee === 'function' ? iteratee(value) : value[iteratee];
+ prop in obj ? obj[prop].push(value) : (obj[prop] = [value]);
+ }
+
+ return obj;
+}
+```
+
+###### References
+- https://lodash.com/docs/4.17.15#groupBy
+
+
+
+#### Q17
+### Create a constructor function which allows its functions present on prototype to be accessed only by the objects created by calling it
+
+- The list of objects created by the function can be kept in track using a collection object inside function
+- `Weakset` can be a prefered way to use as collection for objects created through it as the dereferencing the object helps in garbage collection
+- A context validation within prototype method can be set if the object is created by the function itself or not
+
+```js
+function ProtectedFunction() {
+ const objectCollection = new WeakSet();
+ objectCollection.add(this);
+
+ if (!ProtectedFunction.prototype.method) {
+ ProtectedFunction.prototype.method = function () {
+ if (!objectCollection.has(this)) throw new TypeError('Incompatible object!');
+ return 'Access granted';
+ };
+ }
+}
+
+// driver code
+const protectedObj = new ProtectedFunction();
+protectedObj.method(); // Access granted
+
+const obj = {};
+ProtectedFunction.prototype.method.call(obj); // Incompatible object!
+```
+
+
+
+#### Q18
+### Design a utility on an array of objects where the access can be made to the object using index (as usual) and also from primary key of the object
+```js
+// Example
+const employees = [
+ { name: 'John', id: '1' },
+ { name: 'Jane', id: '2' },
+ { name: 'Pai', id: '0' },
+];
+
+flexEmployees[0] // { name: 'John', id: '1' }
+flexEmployees['Pai'] // { name: 'Pai', id: '0' }
+flexEmployees['doe'] // undefined
+```
+
+- The access to the index happens for arrays by default and the Proxy can be setup to enable the fetching of object using primary key (any other key can also be coded)
+
+```js
+const flexEmployees = new Proxy(employees, {
+ get(target, handler) {
+ if (handler in target) {
+ return target[handler];
+ } else if (typeof handler === 'string') {
+ return target.find(obj => obj.name === handler);
+ } else {
+ return undefined;
+ }
+ },
+});
+```
+
+
+
+#### Q19
+### Write a function which receives an object and returns a true if the object has circular reference
+```js
+// Example
+var circularReferenceObj = { data: 123 };
+circularReferenceObj.myself = circularReferenceObj;
+```
+
+- Stringification of an object having circular references will throw error
+
+```js
+function doesObjectHaveCircularRef(obj){
+ try{
+ JSON.stringify(circularReference);
+ return false;
+ }
+ catch{
+ return true;
+ }
+}
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value
+
+
+
+#### Q20
+### Write a code which can eliminate circular references in an object (Cyclic reference in an object)
+
+- Circular / cyclic reference exists when the object property value forms a cycle
+- The circular references can be eliminated by passing a function to take care of circular references during stringification
+- The circular references can be also be eliminated by setting the such property value to null on the object itself
+
+```js
+const getCircularReplacer = () => {
+ const seen = new WeakSet();
+ return (key, value) => {
+ if (typeof value === 'object' && value !== null) {
+ if (seen.has(value)) {
+ return;
+ }
+ seen.add(value);
+ }
+ return value;
+ };
+};
+
+JSON.stringify(circularReferenceObj, getCircularReplacer());
+```
+
+```js
+function removeCircularRef(obj) {
+ const set = new WeakSet([obj]);
+
+ (function iterateObj(obj = circularReference) {
+ for (let key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ if (typeof obj[key] === 'object')
+ if (set.has(obj[key])) delete obj[key];
+ else {
+ set.add(obj[key]);
+ iterateObj(obj[key]);
+ }
+ }
+ }
+ })();
+}
+```
+
+###### Notes
+`circularReferenceObj` is assumed to be an object with cyclic reference
+
+
+
+#### Q21
+### Provide an object on which a value can be set to nested property even if it does not exist.
+
+- The nested object can be accessed only if all the nested properties are defined on the object
+- A proxy can designed to create such nested object properties on demand whenever such non existent property is requested and attempted to set with value
+- `get` trap of proxy can be used to create the objects dynamically and set the value
+
+```js
+function ProxyObject(obj) {
+ return new Proxy(obj, {
+ get: (target, property) => {
+ if (!(property in target)) {
+ target[property] = new ProxyObject({});
+ }
+ return target[property];
+ },
+ });
+}
+
+// driver code
+const obj = new ProxyObject({});
+obj.x.y.z = 'nested value';
+
+obj.x.y.z; // nested value
+```
+
+
+
+[[↑] Back to top](#home)
diff --git a/challenges/objects-concepts.md b/challenges/objects-concepts.md
new file mode 100644
index 0000000..c85abeb
--- /dev/null
+++ b/challenges/objects-concepts.md
@@ -0,0 +1,661 @@
+
+
+## JavaScript interview code challenges on Objects - concepts
+
+1. [Show the different ways of creating an object](#Q1)
+1. [Display all the keys of an object](#Q2)
+1. [Display all the values of an object](#Q3)
+1. [Write a function which can check if a given object is empty or not](#Q4)
+1. [Create an empty object which has no prototype attached to it](#Q5)
+1. [Show the usage of 'Object.entries' to create an object from key value pairs](#Q6)
+1. [Connect 2 objects so that one object is prototypically connected to the other](#Q7)
+1. [Create an object with getter and setter for property](#Q8)
+1. [Show the different types of accessor properties available for object property and write a code defining them](#Q9)
+1. [Show the different options available to prevent the modifications to the object](#Q10)
+1. [Modify the given object so that it can be used inside a for...of loop](#Q11)
+1. [Stringify an object by excluding the 'password' property](#Q12)
+1. [Write a polyfill for Object.create](#Q13)
+1. [Write a code show Optional chaining for objects and functions](#Q14)
+1. [Show the usage of static variable & function in a class and accessing it from the code](#Q15)
+1. [Write a class which uses private variable and function](#Q16)
+1. [Show how inheritance works in Class and the use of super keyword with working example](#Q17)
+1. [Show the way of using Proxy for object](#Q18)
+1. [Show how can we use for..of loop to iterate on a range with given start and end values in an object](#Q19)
+1. [Prove that private looking variable in a function is not really private specific to that object](#Q20)
+
+---
+
+#### Q1
+### Show the different ways of creating an object
+
+- Object can be created using Object constuctor
+- Object can also be created using Object literal form
+- Object can be created using `new` keyword to constructor function
+- Object can be created using Class
+
+```js
+const object = Object.create({ key: value });
+```
+
+```js
+const object = {
+ key: value
+}
+```
+
+```js
+function getObject(key, value){
+ this[key] = value;
+}
+
+const object = new getObject('key', 'value');
+```
+
+```js
+class Obj {
+ constructor(key, value){
+ this[key] = value;
+ }
+}
+
+const object = new Obj('key', 'value');
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
+
+
+
+#### Q2
+### Display all the keys of an object
+
+- The keys of an object can be obtained using `Object.keys`
+
+```js
+for(let key in obj){
+ if (obj.hasOwnProperty(key)) {
+ console.log(key);
+ }
+}
+```
+
+```js
+for(let key of Object.keys(obj)){
+ if (obj.hasOwnProperty(key)) {
+ console.log(key);
+ }
+}
+```
+
+```js
+Object.keys(obj).forEach((key) => {
+ if (obj.hasOwnProperty(key)) {
+ console.log(key);
+ }
+});
+```
+
+###### Notes
+`obj.hasOwnProperty(key)` is used to only display the properties present on the object and not inherited ones.
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
+
+
+
+#### Q3
+### Display all the values of an object
+
+- The values of an object can be obtained using `Object.values` which returns an array of values
+
+```js
+console.log(Object.values(obj));
+```
+
+```js
+for(let value of Object.values(obj)){
+ console.log(value);
+}
+```
+
+```js
+Object.values(obj).forEach((value) => console.log(value));
+```
+
+```js
+for(let key in obj){
+ if (obj.hasOwnProperty(key)) {
+ console.log(obj[key]);
+ }
+}
+```
+
+###### Notes
+`Object.values` will only fetch the values of the object and not inherited ones
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
+
+
+
+#### Q4
+### Write a function which can check if a given object is empty or not
+
+- Object is empty if it has no keys
+- Few objects such as `Date` object does not have any keys but still are not empty. Hence additional check can be implemented to verify the stringification of the object is also empty
+
+```js
+function isObjectEmpty(obj){
+ if(obj !== null && typeof obj !== "undefined" && typeof obj === "object")
+ return Object.keys(obj).length === 0 && JSON.stringify(obj) === "{}";
+ else
+ return false;
+}
+```
+
+###### Notes
+`obj.constructor === Object` is also used to verify along with the length of keys to check if object is empty which works for objects created with literal form
+
+###### References
+- https://www.samanthaming.com/tidbits/94-how-to-check-if-object-is-empty/
+
+
+
+#### Q5
+### Create an empty object which has no prototype attached to it
+
+- Objects created in JavaScript will have a prototype object on it connected to other object or `Object`
+- Object constructor can be used to create such an empty object
+
+```js
+const obj = Object.create(null);
+```
+
+###### References
+- https://davidwalsh.name/object-create-null
+
+
+
+#### Q6
+### Show the usage of 'Object.entries' to create an object from key value pairs
+
+- The key value pairs can be directly converted to object using `entries` method of Object
+
+```js
+const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];
+const obj = Object.fromEntries(arr);
+```
+
+```js
+const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
+const obj = Object.fromEntries(map);
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
+
+
+
+#### Q7
+### Connect 2 objects so that one object is prototypically connected to the other
+
+- Objects in JavaScript are connected its prototype and is accessible for objects getPrototypeOf or `__proto__`
+- `setPrototypeOf` is used to set the prototype of the object
+
+```js
+const obj1 = { a: 1 };
+const obj2 = { b: 2 };
+obj2.setPrototypeOf(obj1);
+```
+
+```js
+const obj1 = { a: "Object 1 value" };
+const obj2 = { b: "Object 2 value" };
+obj2.__proto__ = obj1;
+```
+
+###### Notes
+The lookup happens at the object level initially and if the key is not found, prototype chain lookup happens
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes
+
+
+
+#### Q8
+### Create an object with getter and setter for property
+
+- `getter` and `setter` on the properties of object can be used to control the read and write behavior
+
+```js
+const obj = {};
+
+Object.defineProperty(obj, 'data', {
+ _data: 0, // closure variable to hold the data
+ get() {
+ return this._data;
+ },
+ set(value) {
+ this._data = value;
+ }
+});
+```
+
+###### Notes
+If the `this.data` is accessed directly, the function will call itself infinitely. Hence, we would require one more variable to store the data
+
+###### References
+- https://javascript.info/property-accessors
+
+
+
+#### Q9
+### Show the different types of accessor properties available for object property and write a code defining them
+
+- `value` accessor is used to set the value of the property
+- `writable` accessor is used to set if the property can be modified or not
+- `configurable` accessor is used to set the property to be configurable or not
+- `enumerable` accessor is to set the property to be considered in enumeration
+
+```js
+var obj = { };
+
+Object.defineProperty(obj, 'prop', {
+ value: 1,
+ writable: true,
+ configurable: true,
+ enumerable: true
+});
+```
+
+###### Notes
+Except `value`, other accessort mentioned accept true or false
+
+###### References
+- https://javascript.info/property-accessors
+
+
+
+#### Q10
+### Show the different options available to prevent the modifications to the object
+
+- `preventExtension` is an Object method which prevents addition of any new property to an object
+- `seal` is an Object method which prevents addition and deletion of any property in an object
+- `freeze` is an Object method which prevents addition, deletion and update of any property of an object
+- There are also methods `isExtensible`, `isSealed` and `isFrozen` on Object to check
+
+```js
+Object.preventExtension(obj);
+Object.isExtensible(obj); // true
+```
+
+```js
+Object.seal(obj);
+Object.isSealed(obj) // true
+```
+
+```js
+Object.freeze(obj);
+Object.isFrozen(obj); // true
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
+
+
+
+#### Q11
+### Modify the given object so that it can be used inside a for...of loop
+
+- Symbol iterator can be used to define the iterator on the object
+- The values of the object can accessed with `for..of` the way we can do it for array
+
+```js
+const obj = {
+ [Symbol.iterator](){
+ const keys = Object.keys(this);
+ let idx = 0;
+ return {
+ next: () => {
+ if(idx >= keys.length)
+ return { value: this[keys[idx++]], done: true };
+ else
+ return { value: this[keys[idx++]], done: false };
+ }
+ }
+ },
+
+ key1: "value1",
+ key2: "value2",
+ key3: "value3"
+}
+```
+
+```js
+const obj = {
+ *[Symbol.iterator]() {
+ for (let key in obj) {
+ yield obj[key];
+ }
+ },
+
+ key1: "value1",
+ key2: "value2",
+ key3: "value3"
+}
+```
+
+###### References
+- https://javascript.info/generators#using-generators-for-iterables
+
+
+
+#### Q12
+### Stringify an object by excluding the 'password' property
+```js
+// Example
+const obj = {
+ id: 1,
+ username: 'John',
+ password: 'secret',
+ email: 'john@email.com',
+};
+```
+
+- `JSON.stringify` is the method which can be used for stringification of an object or any other value
+- It accepts 2nd argument which can be a function or array
+
+```js
+JSON.stringify(obj, (key, value) => key === 'password' ? undefined : value); // {"id":1,"username":"John","email":"john@email.com"}
+```
+
+```js
+JSON.stringify(obj, ['id', 'username', 'email']); // {"id":1,"username":"John","email":"john@email.com"}
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
+
+
+
+#### Q13
+### Write a polyfill for Object.create
+
+- The creating of object can happen by making constructor call to the function
+
+```js
+if (typeof Object.create !== 'function') {
+ Object.create = function (proto, propertiesObject) {
+ if ((typeof proto === 'object' || typeof proto === 'function') &&typeof propertiesObject !== 'undefined') {
+ // F is a dummy empty function
+ function F() {}
+ F.prototype = proto;
+ return new F();
+ } else {
+ throw new TypeError('Invalid proto or properties object');
+ }
+ };
+}
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
+
+
+
+#### Q14
+### Write a code show Optional chaining for objects and functions
+
+- The optional chaining operator (?.) permits reading the value of a property located deep within a chain of connected objects
+- The expression short-circuits with a return value of undefined in the absence of property
+
+```js
+// object property access
+obj.val?.prop;
+
+// object property access through bracket notation
+obj.val?.[expr]
+
+// array index access
+obj.arr?.[index]
+
+// object property access for function call
+obj.func?.(args)
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
+
+
+
+#### Q15
+### Show the usage of static variable & function in a class and accessing it from the code
+
+- Static members of the class are class level variables and not created for each instances of the class
+- Static members can be accessed directly using class name
+
+```js
+class Browser {
+
+ static className = "Browser";
+
+ constructor(os, browserName){
+ this.os = os;
+ this.browserName = browserName;
+ }
+
+ static areTheySameBrowsers(browser1, browser2) {
+ return browser1.browserName === browser2.browserName;
+ }
+}
+
+// driver code
+const browser1 = new Browser("Linux", "Chrome");
+const browser2 = new Browser("Windows", "Firefox");
+
+Browser.className; // Browser
+Browser.areTheySameBrowsers(browser1, browser2); // false
+```
+
+###### References
+- https://javascript.info/static-properties-methods
+
+
+
+#### Q16
+### Write a class which uses private variable and function
+
+- Private members of the class are only accessible within the class and instances of the class do not have access to it
+- Private members can be created with the prefix '#' before the name of the class member
+
+```js
+class ClassWithPrivateFields {
+ #privateVar;
+ publicVar;
+
+ #privatFunc() {
+ this.#privateVar = 7;
+ this.publicVar = 10;
+ }
+
+ publicFunc() {
+ this.#privatFunc();
+ return [this.#privateVar, this.publicVar];
+ }
+}
+
+// driver code
+const instance = new ClassWithPrivateFields();
+
+// can't access private variable
+instance.privateVar; // undefined
+
+// can't access private function
+instance.privatFunc(); // Error
+instance.publicFunc(); // 7, 10
+```
+
+
+
+#### Q17
+### Show how inheritance works in Class and the use of super keyword with working example
+
+- Class level inheritance can happen when a class inherits from another class using the keyword `extends`
+- The child class can access parent class members using the keyword `super`
+- The non private members of parent class become available to child class when inherited
+
+```js
+class BaseComponent {
+ constructor(componentName) {
+ this.componentName = componentName;
+ }
+
+ setState(obj) {
+ this.state = obj;
+ this.render();
+ }
+
+ addValues(props) {
+ return props.reduce((a, b) => a + b);
+ }
+}
+
+class Component extends BaseComponent {
+ constructor(name = '', props) {
+ super(name); // super() is used to call parent class consturctor
+ this.state = { ...props };
+ }
+
+ addValues(...props) {
+ const sum = super.addValues(props); // super.property is used to access parent class property
+ this.setState({ sum, props });
+ }
+
+ render() {
+ console.log(`Sum of ${this.state.props} is ${this.state.sum}`);
+ }
+}
+
+// driver code
+let component = new Component('UI Component');
+component.componentName; // UI Component
+component.addValues(3, 5); // Sum of 3,5 is 8
+component.addValues(9, -4, 6, 2); // Sum of 9,-4,6,2 is 13
+```
+
+###### Notes
+`super` call to constructor within constructor of child class must be the first statement
+
+###### References
+- https://javascript.info/class-inheritance
+
+
+
+#### Q18
+### Show the way of using Proxy for object
+
+- The Proxy object enables create a proxy for another object, which can intercept and redefine fundamental operations for that object
+- Proxy can be set for objects (including functions and arrays) to intercept the values which gives us the control on access and modification of the real object
+- Proxy takes 1st argument as an object / function and 2nd argument as a object with different function traps
+
+```js
+let obj = {
+ key: "value"
+};
+
+let proxy = new Proxy(obj, {
+ get(target, handler){
+ console.log("Proxy get is invoked on target with property: " + handler);
+ return target[handler];
+ },
+ set(target, handler, value){
+ console.log("Proxy set is invoked on target object with property: " + handler + " and value: " + value);
+ target[handler] = value;
+ }
+});
+
+// driver code
+proxy.key2 = "value2"; // Proxy set is invoked on target object with property: key2 and value: value2
+proxy.key1; // Proxy get is invoked on target with property: key1
+```
+
+###### Notes
+There are lot of other traps used in Proxy apart from `get`, `set`, `apply`
+
+###### References
+- https://javascript.info/proxy
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
+
+
+
+#### Q19
+### Show how can we use for..of loop to iterate on a range with given start and end values in an object
+```js
+// Example
+let range = {
+ start: 1,
+ end: 10
+};
+
+for (let i of range) console.log(i); // 1 2 3 4 5 6 7 8 9 10
+```
+
+- For..of loop uses iterator of an object to fetch the values one at a time
+- Defining an iterator Symbol on the object to iterate from start to end will fetch the values of the range
+
+```js
+Object.defineProperty(range, Symbol.iterator, {
+ value: function () {
+ let i = this.start;
+ return {
+ next: () => (i <= this.end ? { value: i++, done: false } : { value: undefined, done: true }),
+ };
+ },
+});
+```
+
+
+
+#### Q20
+### Prove that private looking variable in a function is not really private specific to that object
+
+- Private looking variables can be created in a function and can given access by providing function interfaces
+- The functions maintain a closure over function variables and hence the function variables persist inside the function interfaces
+- Though the variable is private within the function and cannot be accessed, these variables are not private to the created object
+
+```js
+function ObjectCreator() {
+ var privateVar = 0;
+
+ // function interfaces get, set
+ this.getPrivateVar = function () {
+ return privateVar;
+ };
+ this.setPrivateVar = function (value) {
+ privateVar = value;
+ };
+}
+
+// driver code
+var obj = new ObjectCreator();
+obj.setPrivateVar(10);
+obj.getPrivateVar(); // 10
+
+var privateVarAccessor = {
+ get: obj.getPrivateVar,
+ set: obj.setPrivateVar
+};
+
+// obj private variable is accessible by other external entities
+privateVarAccessor.set(5);
+privateVarAccessor.get(); // 5
+obj.getPrivateVar(); // 10
+```
+
+
+
+[[↑] Back to top](#home)
diff --git a/challenges/objects.md b/challenges/objects.md
deleted file mode 100644
index 18a74f8..0000000
--- a/challenges/objects.md
+++ /dev/null
@@ -1,1372 +0,0 @@
-
-
-## JavaScript interview code challenges on Objects
-
-1. [Show the different ways of creating an object](#Q1)
-2. [Display all the keys of an object](#Q2)
-3. [Display all the values of an object](#Q3)
-4. [Write a function which can check if a given object is empty or not](#Q4)
-5. [Display all the keys and values of a nested object](#Q5)
-6. [Write a program which can empty a given object](#Q6)
-7. [Show how a deep copy of an object can be done](#Q7)
-8. [Create an empty object which has no prototype attached to it](#Q8)
-9. [Create an array of pair of values (key, value) from an object and store it in a map. Consider the object is not nested](#Q9)
-10. [Show the usage of 'Object.entries' to create an object from key value pairs](#Q10)
-11. [Connect 2 objects so that one object is prototypically connected to the other](#Q11)
-12. [Create an object with getter and setter for property](#Q12)
-13. [Show the different types of accessor properties available for object property and write a code defining them](#Q13)
-14. [Create an object with a property 'marks' which cannot be set to a value less than 0](#Q14)
-15. [Create an object which has a property 'userid' which can only be set once and will be a read only property](#Q15)
-16. [Show the different options available to prevent the modifications to the object](#Q16)
-17. [Design a function which takes an array as input and returns a function 'next', calling which fetches a value one by one](#Q17)
-18. [Modify the given object so that it can be used inside a for...of loop](#Q18)
-19. [Stringify an object by excluding the 'password' property](#Q19)
-20. [Create an object 'obj' with functions assigned to keys. Show how can we achieve 'obj.func1().func2().func3()' considering func1, func2, func3 are object keys](#Q20)
-21. [Write a polyfill for Object.create](#Q21)
-22. [Write a code show Optional chaining for objects and functions](#Q22)
-23. [Create an object with property counter which keeps incrementing on every access](#Q23)
-24. [Create an object and make it behave like an array which allows push and pop operations on items](#Q24)
-25. [Write a function which can be used to deeply compare 2 nested objects](#Q25)
-26. [Design a class for employee which takes id and name in during construction of object and has a salary property](#Q26)
-27. [Show the usage of static variable & function in a class and accessing it from the code](#Q27)
-28. [Write a class which uses private variable and function](#Q28)
-29. [Show how inheritance works in Class and the use of super keyword with working example](#Q29)
-30. [Show the way of using Proxy for object](#Q30)
-31. [Write a program to make all the properties of an object ready only but allow the addition of new properties](#Q31)
-32. [Show how can we use for..of loop to iterate on a range with given start and end values in an object](#Q32)
-33. [Write a program which can return a boolean if value is present in the range with given start and end values in an object](#Q33)
-34. [Write a function which accepts a topic and a list of related tags to store the information. The same function should return all the topics when requested with a tagname](#Q34)
-35. [Prove that private looking variable in a function is not really private specific to that object](#Q35)
-36. [Write a function which accepts a collection of values & an iteratee as arguments and returns a grouped object](#Q36)
-37. [Create a constructor function which allows its functions present on prototype to be accessed only by the objects created by calling it](#Q37)
-38. [Design a utility on an array of objects where the access can be made to the object using index (as usual) and also from primary key of the object](#Q38)
-39. [Write a function which receives an object and returns a true if the object has circular reference](#Q39)
-40. [Write a code which can eliminate circular references in an object (Cyclic reference in an object)](#Q40)
-41. [Provide an object on which a value can be set to nested property even if it does not exist](#Q41)
-
----
-
-#### Q1
-### Show the different ways of creating an object
-
-- Object can be created using Object constuctor
-- Object can also be created using Object literal form
-- Object can be created using `new` keyword to constructor function
-- Object can be created using Class
-
-```js
-const object = Object.create({ key: value });
-```
-
-```js
-const object = {
- key: value
-}
-```
-
-```js
-function getObject(key, value){
- this[key] = value;
-}
-
-const object = new getObject('key', 'value');
-```
-
-```js
-class Obj {
- constructor(key, value){
- this[key] = value;
- }
-}
-
-const object = new Obj('key', 'value');
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
-
-
-
-#### Q2
-### Display all the keys of an object
-
-- The keys of an object can be obtained using `Object.keys`
-
-```js
-for(let key in obj){
- if (obj.hasOwnProperty(key)) {
- console.log(key);
- }
-}
-```
-
-```js
-for(let key of Object.keys(obj)){
- if (obj.hasOwnProperty(key)) {
- console.log(key);
- }
-}
-```
-
-```js
-Object.keys(obj).forEach((key) => {
- if (obj.hasOwnProperty(key)) {
- console.log(key);
- }
-});
-```
-
-###### Notes
-`obj.hasOwnProperty(key)` is used to only display the properties present on the object and not inherited ones.
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
-
-
-
-#### Q3
-### Display all the values of an object
-
-- The values of an object can be obtained using `Object.values` which returns an array of values
-
-```js
-console.log(Object.values(obj));
-```
-
-```js
-for(let value of Object.values(obj)){
- console.log(value);
-}
-```
-
-```js
-Object.values(obj).forEach((value) => console.log(value));
-```
-
-```js
-for(let key in obj){
- if (obj.hasOwnProperty(key)) {
- console.log(obj[key]);
- }
-}
-```
-
-###### Notes
-`Object.values` will only fetch the values of the object and not inherited ones
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
-
-
-
-#### Q4
-### Write a function which can check if a given object is empty or not
-
-- Object is empty if it has no keys
-- Few objects such as `Date` object does not have any keys but still are not empty. Hence additional check can be implemented to verify the stringification of the object is also empty
-
-```js
-function isObjectEmpty(obj){
- if(obj !== null && typeof obj !== "undefined" && typeof obj === "object")
- return Object.keys(obj).length === 0 && JSON.stringify(obj) === "{}";
- else
- return false;
-}
-```
-
-###### Notes
-`obj.constructor === Object` is also used to verify along with the length of keys to check if object is empty which works for objects created with literal form
-
-###### References
-- https://www.samanthaming.com/tidbits/94-how-to-check-if-object-is-empty/
-
-
-
-#### Q5
-### Display all the keys and values of a nested object
-
-- `typeof` operator on value gives the type of value
-- Recursive solution can be used to iterate over all the nested objects
-
-```js
-function keyValuePrinter(obj){
- for(let key in obj){
- if(typeof obj[key] !== "object"){
- console.log("[" + key + " : " + obj[key] + "]");
- }
- else{
- keyValuePrinter(obj[key]);
- }
- }
-}
-```
-
-
-
-#### Q6
-### Write a program which can empty a given object
-
-- Object can be emptied by removing all the keys present on it
-- Alternatively, a new object can be created and the prototype of the new object can be set as prototype of old object
-
-```js
-for(let key in obj){
- if(obj.hasOwnProperty(key)){
- delete obj[key];
- }
-}
-```
-
-```js
-const newObj = {};
-Object.setPrototypeOf(newObj, obj);
-```
-
-###### Notes
-'obj' is considered to be the object to be emptied
-
-
-
-#### Q7
-### Show how a deep copy of an object can be done
-
-- Deep copy is done by copying all the properties of the object to another object
-
-```js
-const x = Object.assign({}, obj);
-```
-
-```js
-const x = { ...obj};
-```
-
-```js
-const x = JSON.parse(JSON.stringify(obj));
-```
-
-###### Notes
-3rd solution provided does deep copy of a nested object also but this technique results in loss of data
-
-###### References
-- https://www.digitalocean.com/community/tutorials/copying-objects-in-javascript
-
-
-
-#### Q8
-### Create an empty object which has no prototype attached to it
-
-- Objects created in JavaScript will have a prototype object on it connected to other object or `Object`
-- Object constructor can be used to create such an empty object
-
-```js
-const obj = Object.create(null);
-```
-
-###### References
-- https://davidwalsh.name/object-create-null
-
-
-
-#### Q9
-### Create an array of pair of values (key, value) from an object and store it in a map. Consider the object is not nested
-
-- As the object is not nested, the key-value pairs can be obtained directly by using Object.entries
-- Map can be initialized with key-value pairs
-
-```js
-const map = new Map(Object.entries(obj));
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
-
-
-
-#### Q10
-### Show the usage of 'Object.entries' to create an object from key value pairs
-
-- The key value pairs can be directly converted to object using `entries` method of Object
-
-```js
-const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];
-const obj = Object.fromEntries(arr);
-```
-
-```js
-const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
-const obj = Object.fromEntries(map);
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
-
-
-
-#### Q11
-### Connect 2 objects so that one object is prototypically connected to the other
-
-- Objects in JavaScript are connected its prototype and is accessible for objects getPrototypeOf or `__proto__`
-- `setPrototypeOf` is used to set the prototype of the object
-
-```js
-const obj1 = { a: 1 };
-const obj2 = { b: 2 };
-obj2.setPrototypeOf(obj1);
-```
-
-```js
-const obj1 = { a: "Object 1 value" };
-const obj2 = { b: "Object 2 value" };
-obj2.__proto__ = obj1;
-```
-
-###### Notes
-The lookup happens at the object level initially and if the key is not found, prototype chain lookup happens
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes
-
-
-
-#### Q12
-### Create an object with getter and setter for property
-
-- `getter` and `setter` on the properties of object can be used to control the read and write behavior
-
-```js
-const obj = {};
-
-Object.defineProperty(obj, 'data', {
- _data: 0, // closure variable to hold the data
- get() {
- return this._data;
- },
- set(value) {
- this._data = value;
- }
-});
-```
-
-###### Notes
-If the `this.data` is accessed directly, the function will call itself infinitely. Hence, we would require one more variable to store the data
-
-###### References
-- https://javascript.info/property-accessors
-
-
-
-#### Q13
-### Show the different types of accessor properties available for object property and write a code defining them
-
-- `value` accessor is used to set the value of the property
-- `writable` accessor is used to set if the property can be modified or not
-- `configurable` accessor is used to set the property to be configurable or not
-- `enumerable` accessor is to set the property to be considered in enumeration
-
-```js
-var obj = { };
-
-Object.defineProperty(obj, 'prop', {
- value: 1,
- writable: true,
- configurable: true,
- enumerable: true
-});
-```
-
-###### Notes
-Except `value`, other accessort mentioned accept true or false
-
-###### References
-- https://javascript.info/property-accessors
-
-
-
-#### Q14
-### Create an object with a property 'marks' which cannot be set to a value less than 0
-
-- `getter` and `setter` on the properties of object can be used to control the read and write behavior
-
-```js
-const obj = { marks: 0 };
-
-Object.defineProperty(obj, 'marks', {
- set(value) {
- if(value < 0)
- throw new Error("Marks cant be less than zero");
- marks = value;
- },
- get() {
- return marks;
- }
-});
-```
-
-```js
-const obj = {
- _marks: 0,
-
- set marks(value){
- if(value < 0)
- throw new Error("Marks cant be less than zero");
- this._marks = value;
- },
-
- get marks(){
- return this._marks;
- }
-}
-```
-
-###### Notes
-2nd solution shown directly defines `getter` and `setter` for property marks, hence uses another variable to store the data
-
-###### References
-- https://javascript.info/property-accessors
-
-
-
-#### Q15
-### Create an object which has a property 'userid' which can only be set once and will be a read only property
-
-- Property accessor `writable` to true sets the property to be read only
-
-```js
-function userObjectCreator(id){
- const obj = { };
-
- Object.defineProperty(obj, 'userid', {
- value: id,
- writable: false
- });
-
- return obj;
-}
-
-const obj = userObjectCreator(1);
-```
-
-###### Notes
-`obj.id` is a ready only property and does not allow overwriting
-
-
-
-#### Q16
-### Show the different options available to prevent the modifications to the object
-
-- `preventExtension` is an Object method which prevents addition of any new property to an object
-- `seal` is an Object method which prevents addition and deletion of any property in an object
-- `freeze` is an Object method which prevents addition, deletion and update of any property of an object
-- There are also methods `isExtensible`, `isSealed` and `isFrozen` on Object to check
-
-```js
-Object.preventExtension(obj);
-Object.isExtensible(obj); // true
-```
-
-```js
-Object.seal(obj);
-Object.isSealed(obj) // true
-```
-
-```js
-Object.freeze(obj);
-Object.isFrozen(obj); // true
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
-
-
-
-#### Q17
-### Design a function which takes an array as input and returns a function 'next', calling which fetches a value one by one
-
-- The function returned `next` will return an object which contains value and done properties
-
-```js
-function makeIterator(array) {
- let nextIndex = 0;
- return {
- next: function () {
- return nextIndex < array.length
- ? {
- value: array[nextIndex++],
- done: false,
- }
- : {
- done: true,
- };
- },
- };
-}
-
-// driver code
-let it = makeIterator(['yo', 'ya']);
-it.next().value; // 'yo'
-it.next().value; // 'ya'
-it.next().done; // true
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
-
-
-
-#### Q18
-### Modify the given object so that it can be used inside a for...of loop
-
-- Symbol iterator can be used to define the iterator on the object
-- The values of the object can accessed with `for..of` the way we can do it for array
-
-```js
-const obj = {
- [Symbol.iterator](){
- const keys = Object.keys(this);
- let idx = 0;
- return {
- next: () => {
- if(idx >= keys.length)
- return { value: this[keys[idx++]], done: true };
- else
- return { value: this[keys[idx++]], done: false };
- }
- }
- },
-
- key1: "value1",
- key2: "value2",
- key3: "value3"
-}
-```
-
-```js
-const obj = {
- *[Symbol.iterator]() {
- for (let key in obj) {
- yield obj[key];
- }
- },
-
- key1: "value1",
- key2: "value2",
- key3: "value3"
-}
-```
-
-###### References
-- https://javascript.info/generators#using-generators-for-iterables
-
-
-
-#### Q19
-### Stringify an object by excluding the 'password' property
-```js
-// Example
-const obj = {
- id: 1,
- username: 'John',
- password: 'secret',
- email: 'john@email.com',
-};
-```
-
-- `JSON.stringify` is the method which can be used for stringification of an object or any other value
-- It accepts 2nd argument which can be a function or array
-
-```js
-JSON.stringify(obj, (key, value) => key === 'password' ? undefined : value); // {"id":1,"username":"John","email":"john@email.com"}
-```
-
-```js
-JSON.stringify(obj, ['id', 'username', 'email']); // {"id":1,"username":"John","email":"john@email.com"}
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
-
-
-
-#### Q20
-### Create an object 'obj' with functions assigned to keys. Show how can we achieve 'obj.func1().func2().func3()' considering func1, func2, func3 are object keys
-
-- For achieving chaining functionality, each function can return the calling context itself so that context is retained
-
-```js
-var obj = {
- id: 1,
- username: "Jane",
- dept: "Computers",
-
- displayId(){
- console.log("Id: " + this.id);
- return this;
- },
-
- displayName(){
- console.log("Name: " + this.username);
- return this;
- },
-
- displayDept(dept){
- if(typeof dept !== "undefined"){
- this.dept = dept;
- }
- console.log("Dept: " + this.dept);
- return this;
- }
-}
-
-// driver code
-obj.displayId().displayName().displayDept("Info Tech");
-```
-
-###### Notes
-Order of calling the functions does not matter as all the functions are returning object itself
-
-###### References
-- https://medium.com/technofunnel/javascript-function-chaining-8b2fbef76f7f
-
-
-
-#### Q21
-### Write a polyfill for Object.create
-
-- The creating of object can happen by making constructor call to the function
-
-```js
-if (typeof Object.create !== 'function') {
- Object.create = function (proto, propertiesObject) {
- if ((typeof proto === 'object' || typeof proto === 'function') &&typeof propertiesObject !== 'undefined') {
- // F is a dummy empty function
- function F() {}
- F.prototype = proto;
- return new F();
- } else {
- throw new TypeError('Invalid proto or properties object');
- }
- };
-}
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
-
-
-
-#### Q22
-### Write a code show Optional chaining for objects and functions
-
-- The optional chaining operator (?.) permits reading the value of a property located deep within a chain of connected objects
-- The expression short-circuits with a return value of undefined in the absence of property
-
-```js
-// object property access
-obj.val?.prop;
-
-// object property access through bracket notation
-obj.val?.[expr]
-
-// array index access
-obj.arr?.[index]
-
-// object property access for function call
-obj.func?.(args)
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
-
-
-
-#### Q23
-### Create an object with property counter which keeps incrementing on every access
-```js
-const obj = counterObject();
-obj.counter; // 1
-obj.counter; // 2
-obj.counter; // 3
-```
-
-- The access to the property of the object can be configured through property `getter`
-- A separate private variable can be maintained track the value and getter on each access to increment and return the value
-
-```js
-function counterObject() {
- const symCounter = Symbol('counter');
-
- const obj = {
- [symCounter]: 0,
-
- get counter() {
- return ++this[symCounter];
- },
-
- set counter(value) {
- throw new Error('Cannot set the counter');
- },
- };
- return obj;
-}
-```
-
-###### Notes
-Symbol is used to maintain the private variable in the object. Using the private variable to store the data such as `_counter` is also a well known pattern before symbols
-
-
-
-#### Q24
-### Create an object and make it behave like an array which allows push and pop operations on items
-
-- Object does not have by default a property named 'length' and hence we can define it on object which helps to track the length
-- 'push' and 'pop' functions can be added to the object which internally calls the Array methods `push` and `pop` by passing the object context
-
-```js
-const arrayLikeObject = {
- length: 0,
- push: function (item) {
- Array.prototype.push.call(this, item);
- },
- pop: function () {
- Array.prototype.pop.call(this);
- }
-};
-
-// driver code
-arrayLikeObject.push('first');
-arrayLikeObject.push('second');
-arrayLikeObject.pop();
-arrayLikeObject; // { length: 1, 0: first }
-```
-
-###### Notes
-As the context for array methods is set object, length of the object changes whenever `push` and `pop` operations take place
-
-
-
-#### Q25
-### Write a function which can be used to deeply compare 2 nested objects
-```js
-// Example
-const obj1 = {
- name: 'John',
- details: {
- x: 1,
- y: 2,
- },
-};
-
-const obj2 = {
- name: 'John',
- details: {
- y: 2,
- x: 1,
- },
-};
-
-deepEqual(obj1, obj2); // true
-```
-
-- The objects can be deeply compared by checking the key value pairs recursively
-
-```js
-function deepEqual(object1, object2) {
- const keys1 = Object.keys(object1);
- const keys2 = Object.keys(object2);
-
- if (keys1.length !== keys2.length) {
- return false;
- }
-
- for (const key of keys1) {
- const val1 = object1[key];
- const val2 = object2[key];
- const areObjects = val1 != null && typeof val1 === 'object' && val1 != null && typeof val2 === 'object';
- if ((areObjects && !deepEqual(val1, val2)) || (!areObjects && val1 !== val2)) {
- return false;
- }
- }
-
- return true;
-}
-```
-
-###### Notes
-Stringification of both objects and comparision will also work, but fails on keys order mismatch
-
-###### References
-- https://dmitripavlutin.com/how-to-compare-objects-in-javascript/
-
-
-
-#### Q26
-### Design a class for employee which takes id and name in during construction of object and has a salary property
-
-- Classes are a template for creating objects. They encapsulate data with code to work on that data
-- The constructor method is a special method for creating and initializing an object created with a class
-- Objects of the class can be created using `new` keyword followed by classname
-
-```js
-class Employee {
- constructor(id, name) {
- if (typeof id !== 'undefined' && typeof name !== 'undefined') {
- this.id = id;
- this.name = name;
- } else
- throw new Error('Employee id and name are mandatory for new employee creation');
- }
-
- getId() {
- return this.id;
- }
-
- getName() {
- return this.name;
- }
-
- setSalary(base, variable) {
- this.salary = base + variable;
- }
-
- getSalary() {
- return this.salary;
- }
-}
-
-// driver code
-const emp = new Employee(1, "John Doe");
-emp.setSalary(10000, 1000);
-emp.getSalary(); // 11000
-```
-
-###### Notes
-Class in JavaScript is functionality to achieve class based model on top of prototype based programming model of JavaScript
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
-
-
-
-#### Q27
-### Show the usage of static variable & function in a class and accessing it from the code
-
-- Static members of the class are class level variables and not created for each instances of the class
-- Static members can be accessed directly using class name
-
-```js
-class Browser {
-
- static className = "Browser";
-
- constructor(os, browserName){
- this.os = os;
- this.browserName = browserName;
- }
-
- static areTheySameBrowsers(browser1, browser2) {
- return browser1.browserName === browser2.browserName;
- }
-}
-
-// driver code
-const browser1 = new Browser("Linux", "Chrome");
-const browser2 = new Browser("Windows", "Firefox");
-
-Browser.className; // Browser
-Browser.areTheySameBrowsers(browser1, browser2); // false
-```
-
-###### References
-- https://javascript.info/static-properties-methods
-
-
-
-#### Q28
-### Write a class which uses private variable and function
-
-- Private members of the class are only accessible within the class and instances of the class do not have access to it
-- Private members can be created with the prefix '#' before the name of the class member
-
-```js
-class ClassWithPrivateFields {
- #privateVar;
- publicVar;
-
- #privatFunc() {
- this.#privateVar = 7;
- this.publicVar = 10;
- }
-
- publicFunc() {
- this.#privatFunc();
- return [this.#privateVar, this.publicVar];
- }
-}
-
-// driver code
-const instance = new ClassWithPrivateFields();
-
-// can't access private variable
-instance.privateVar; // undefined
-
-// can't access private function
-instance.privatFunc(); // Error
-instance.publicFunc(); // 7, 10
-```
-
-
-
-#### Q29
-### Show how inheritance works in Class and the use of super keyword with working example
-
-- Class level inheritance can happen when a class inherits from another class using the keyword `extends`
-- The child class can access parent class members using the keyword `super`
-- The non private members of parent class become available to child class when inherited
-
-```js
-class BaseComponent {
- constructor(componentName) {
- this.componentName = componentName;
- }
-
- setState(obj) {
- this.state = obj;
- this.render();
- }
-
- addValues(props) {
- return props.reduce((a, b) => a + b);
- }
-}
-
-class Component extends BaseComponent {
- constructor(name = '', props) {
- super(name); // super() is used to call parent class consturctor
- this.state = { ...props };
- }
-
- addValues(...props) {
- const sum = super.addValues(props); // super.property is used to access parent class property
- this.setState({ sum, props });
- }
-
- render() {
- console.log(`Sum of ${this.state.props} is ${this.state.sum}`);
- }
-}
-
-// driver code
-let component = new Component('UI Component');
-component.componentName; // UI Component
-component.addValues(3, 5); // Sum of 3,5 is 8
-component.addValues(9, -4, 6, 2); // Sum of 9,-4,6,2 is 13
-```
-
-###### Notes
-`super` call to constructor within constructor of child class must be the first statement
-
-###### References
-- https://javascript.info/class-inheritance
-
-
-
-#### Q30
-### Show the way of using Proxy for object
-
-- The Proxy object enables create a proxy for another object, which can intercept and redefine fundamental operations for that object
-- Proxy can be set for objects (including functions and arrays) to intercept the values which gives us the control on access and modification of the real object
-- Proxy takes 1st argument as an object / function and 2nd argument as a object with different function traps
-
-```js
-let obj = {
- key: "value"
-};
-
-let proxy = new Proxy(obj, {
- get(target, handler){
- console.log("Proxy get is invoked on target with property: " + handler);
- return target[handler];
- },
- set(target, handler, value){
- console.log("Proxy set is invoked on target object with property: " + handler + " and value: " + value);
- target[handler] = value;
- }
-});
-
-// driver code
-proxy.key2 = "value2"; // Proxy set is invoked on target object with property: key2 and value: value2
-proxy.key1; // Proxy get is invoked on target with property: key1
-```
-
-###### Notes
-There are lot of other traps used in Proxy apart from `get`, `set`, `apply`
-
-###### References
-- https://javascript.info/proxy
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
-
-
-
-#### Q31
-### Write a program to make all the properties of an object ready only but allow the addition of new properties
-
-- The exisiting properties of the object can be made read only with `set` keyword using Proxy
-
-```js
-const readOnlyObj = new Proxy(obj, {
- get: function (target, key) {
- return target[key];
- },
-
- set: function() {
- if(target.hasOwnProperty(key)){
- throw new Error("Object properties are read only");
- }
- target[key] = value;
- }
-});
-```
-
-###### Notes
-If condition takes care whether the property is new or existing to handle the read only scenario
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
-
-
-
-#### Q32
-### Show how can we use for..of loop to iterate on a range with given start and end values in an object
-```js
-// Example
-let range = {
- start: 1,
- end: 10
-};
-
-for (let i of range) console.log(i); // 1 2 3 4 5 6 7 8 9 10
-```
-
-- For..of loop uses iterator of an object to fetch the values one at a time
-- Defining an iterator Symbol on the object to iterate from start to end will fetch the values of the range
-
-```js
-Object.defineProperty(range, Symbol.iterator, {
- value: function () {
- let i = this.start;
- return {
- next: () => (i <= this.end ? { value: i++, done: false } : { value: undefined, done: true }),
- };
- },
-});
-```
-
-
-
-#### Q33
-### Write a program which can return a boolean if value is present in the range with given start and end values in an object
-```js
-// Example
-let range = {
- start: 10,
- end: 50
-};
-
-5 in range; // false
-25 in range; // true
-```
-
-- The object `in` can be trapped using Proxy trap `has`, to check if the value is in the range or not
-
-```js
-range = new Proxy(range, {
- has(target, value){
- return value >= target.start && value <= target.end;
- }
-});
-```
-
-
-
-#### Q34
-### Write a function which accepts a topic and a list of related tags to store the information. The same function should return all the topics when requested with a tagname
-```js
-// Example
-const tagManager = TagManager();
-tagManager.addTags('React', 'Redux, JSX, JavaScript, VDOM');
-tagManager.addTags('Angular', 'RxJS, TypeScript, JavaScript');
-tagManager.addTags('Vue', 'VDOM, JavaScript');
-
-tagManager.getTopics.getTopics('VDOM'); // React, Vue
-tagManager.getTopics.getTopics('JavaScript'); // React, Angular, Vue
-```
-
-- The tags can be stored as keys and array of topics as values in a map
-- Function module can be desgined to expose 'addTags' and 'getTopics' by tagname
-
-```js
-function TagManager() {
- const map = new Map();
-
- function addTags(topic, tagText) {
- const tagsArr = tagText.split(',').map(tag => tag.trim());
-
- tagsArr.forEach(tag => {
- if (map.has(tag)) {
- map.get(tag).push(topic);
- } else {
- map.set(tag, [topic]);
- }
- });
- }
-
- function getTopics(tag) {
- return map.get(tag);
- }
-
- return {
- addTags,
- getTopics
- }
-}
-```
-
-
-
-#### Q35
-### Prove that private looking variable in a function is not really private specific to that object
-
-- Private looking variables can be created in a function and can given access by providing function interfaces
-- The functions maintain a closure over function variables and hence the function variables persist inside the function interfaces
-- Though the variable is private within the function and cannot be accessed, these variables are not private to the created object
-
-```js
-function ObjectCreator() {
- var privateVar = 0;
-
- // function interfaces get, set
- this.getPrivateVar = function () {
- return privateVar;
- };
- this.setPrivateVar = function (value) {
- privateVar = value;
- };
-}
-
-// driver code
-var obj = new ObjectCreator();
-obj.setPrivateVar(10);
-obj.getPrivateVar(); // 10
-
-var privateVarAccessor = {
- get: obj.getPrivateVar,
- set: obj.setPrivateVar
-};
-
-// obj private variable is accessible by other external entities
-privateVarAccessor.set(5);
-privateVarAccessor.get(); // 5
-obj.getPrivateVar(); // 10
-```
-
-
-
-#### Q36
-### Write a function which accepts a collection of values & an iteratee as arguments and returns a grouped object
-```js
-// Example
-groupBy([6.1, 4.2, 6.3], Math.floor); // { 6: [6.1, 6.3], 4: [4.2] }
-groupBy(['one', 'two', 'three'], 'length'); // { 3: ['one', 'two'], 5: ['three'] }
-```
-
-- As the 2nd argument is either a functin or property, the iteratee can be perfrom accordingly on the value of arrays
-- An empty object can be created and used to push the values of array to respective property of the iteratee output
-
-```js
-function groupBy(values, iteratee) {
- const obj = {};
- for (let value of values) {
- const prop = typeof iteratee === 'function' ? iteratee(value) : value[iteratee];
- prop in obj ? obj[prop].push(value) : (obj[prop] = [value]);
- }
-
- return obj;
-}
-```
-
-###### References
-- https://lodash.com/docs/4.17.15#groupBy
-
-
-
-#### Q37
-### Create a constructor function which allows its functions present on prototype to be accessed only by the objects created by calling it
-
-- The list of objects created by the function can be kept in track using a collection object inside function
-- `Weakset` can be a prefered way to use as collection for objects created through it as the dereferencing the object helps in garbage collection
-- A context validation within prototype method can be set if the object is created by the function itself or not
-
-```js
-function ProtectedFunction() {
- const objectCollection = new WeakSet();
- objectCollection.add(this);
-
- if (!ProtectedFunction.prototype.method) {
- ProtectedFunction.prototype.method = function () {
- if (!objectCollection.has(this)) throw new TypeError('Incompatible object!');
- return 'Access granted';
- };
- }
-}
-
-// driver code
-const protectedObj = new ProtectedFunction();
-protectedObj.method(); // Access granted
-
-const obj = {};
-ProtectedFunction.prototype.method.call(obj); // Incompatible object!
-```
-
-
-
-#### Q38
-### Design a utility on an array of objects where the access can be made to the object using index (as usual) and also from primary key of the object
-```js
-// Example
-const employees = [
- { name: 'John', id: '1' },
- { name: 'Jane', id: '2' },
- { name: 'Pai', id: '0' },
-];
-
-flexEmployees[0] // { name: 'John', id: '1' }
-flexEmployees['Pai'] // { name: 'Pai', id: '0' }
-flexEmployees['doe'] // undefined
-```
-
-- The access to the index happens for arrays by default and the Proxy can be setup to enable the fetching of object using primary key (any other key can also be coded)
-
-```js
-const flexEmployees = new Proxy(employees, {
- get(target, handler) {
- if (handler in target) {
- return target[handler];
- } else if (typeof handler === 'string') {
- return target.find(obj => obj.name === handler);
- } else {
- return undefined;
- }
- },
-});
-```
-
-
-
-#### Q39
-### Write a function which receives an object and returns a true if the object has circular reference
-```js
-// Example
-var circularReferenceObj = { data: 123 };
-circularReferenceObj.myself = circularReferenceObj;
-```
-
-- Stringification of an object having circular references will throw error
-
-```js
-function doesObjectHaveCircularRef(obj){
- try{
- JSON.stringify(circularReference);
- return false;
- }
- catch{
- return true;
- }
-}
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value
-
-
-
-#### Q40
-### Write a code which can eliminate circular references in an object (Cyclic reference in an object)
-
-- Circular / cyclic reference exists when the object property value forms a cycle
-- The circular references can be eliminated by passing a function to take care of circular references during stringification
-- The circular references can be also be eliminated by setting the such property value to null on the object itself
-
-```js
-const getCircularReplacer = () => {
- const seen = new WeakSet();
- return (key, value) => {
- if (typeof value === 'object' && value !== null) {
- if (seen.has(value)) {
- return;
- }
- seen.add(value);
- }
- return value;
- };
-};
-
-JSON.stringify(circularReferenceObj, getCircularReplacer());
-```
-
-```js
-function removeCircularRef(obj) {
- const set = new WeakSet([obj]);
-
- (function iterateObj(obj = circularReference) {
- for (let key in obj) {
- if (obj.hasOwnProperty(key)) {
- if (typeof obj[key] === 'object')
- if (set.has(obj[key])) delete obj[key];
- else {
- set.add(obj[key]);
- iterateObj(obj[key]);
- }
- }
- }
- })();
-}
-```
-
-###### Notes
-`circularReferenceObj` is assumed to be an object with cyclic reference
-
-
-
-#### Q41
-### Provide an object on which a value can be set to nested property even if it does not exist.
-
-- The nested object can be accessed only if all the nested properties are defined on the object
-- A proxy can designed to create such nested object properties on demand whenever such non existent property is requested and attempted to set with value
-- `get` trap of proxy can be used to create the objects dynamically and set the value
-
-```js
-function ProxyObject(obj) {
- return new Proxy(obj, {
- get: (target, property) => {
- if (!(property in target)) {
- target[property] = new ProxyObject({});
- }
- return target[property];
- },
- });
-}
-
-// driver code
-const obj = new ProxyObject({});
-obj.x.y.z = 'nested value';
-
-obj.x.y.z; // nested value
-```
-
-
-
-[[↑] Back to top](#home)
diff --git a/challenges/primitives-challenges.md b/challenges/primitives-challenges.md
new file mode 100644
index 0000000..a3e718e
--- /dev/null
+++ b/challenges/primitives-challenges.md
@@ -0,0 +1,471 @@
+
+
+## JavaScript interview code challenges on Primitives - challenges
+
+1. [Swap 2 integers present in variables num1 and num2 without using temporary variable](#Q1)
+1. [Write a function which returns true if given value of number is an integer without using any inbuilt functions](#Q2)
+1. [Create a function which returns a random number in the given range of values both inclusive](#Q3)
+1. [Write a program to reverse a string](#Q4)
+1. [Write a program to reverse a string by words. Also show the reverse of each words in place](#Q5)
+1. [Write a program to reverse a given integer number](#Q6)
+1. [Write a code to replace all the spaces of the string with underscores](#Q7)
+1. [Write a function which can convert the time input given in 12 hours format to 24 hours format](#Q8)
+1. [Write a function which accepts a string argument and returns the count of characters between the first and last character 'X'](#Q9)
+1. [Write a function to truncate a string to a certain number of letters](#Q10)
+1. [Write a code to truncate a string to a certain number of words](#Q11)
+1. [Create a regular expression to validate if the given input is valid Indian mobile number or not](#Q12)
+1. [Write a function which returns a list of elements which contains at least one character as digit](#Q13)
+1. [Write a function which checks if a given search text is present either in the beginning of the first name or the second name](#Q14)
+1. [Write a function to chop a string into chunks of a given length and return it as array](#Q15)
+1. [Write a code to remove all the vowels from a given string](#Q16)
+1. [Create a function which returns random hex color code](#Q17)
+1. [Write a function which accepts two valid dates and returns the difference between them as number of days](#Q18)
+
+---
+
+#### Q1
+### Swap 2 integers present in variables num1 and num2 without using temporary variable
+
+- The swapping of 2 variables is possible with simple Destructuring assignment using array
+- Traditional approach of swapping by using the given variables is also achievable
+
+```js
+let num1 = 10, num2 = 20;
+[num1, num2] = [num2, num1];
+```
+
+```js
+let num1 = 10, num2 = 20;
+num1 = num1 + num2;
+num2 = num1 - num2;
+num1 = num1 - num2;
+```
+
+###### Notes
+2nd solution can fail due to overflow of number range if the numbers are very big
+
+
+
+#### Q2
+### Write a function which returns true if given value of number is an integer without using any inbuilt functions
+```js
+// Example
+isInt(4.0); // true
+isInt(12.2); // false
+isInt(0.3); // false
+```
+- Modulo operator can be used to check if there is a remainder left when divided by 1
+
+```js
+function isInt(value){
+ return value % 1 === 0;
+}
+```
+
+
+
+#### Q3
+### Create a function which returns a random number in the given range of values both inclusive
+
+- `Math.random` function returns a floating-point, pseudo-random number between 0 (inclusive) and 1 (exclusive)
+
+```js
+function randomNumberGeneratorInRange(rangeStart, rangeEnd){
+ return rangeStart + Math.round(Math.random() * (rangeEnd - rangeStart));
+}
+
+randomNumberGeneratorInRange(10, 50); // 12
+```
+
+###### Notes
+Usage of `Math.round` depends on the logic used to accomplish the requirement
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
+
+
+
+#### Q4
+### Write a program to reverse a string
+
+- String can be reversed by iterating it and storing it in reverse order
+- String can also be reversed by converting it to array, then joining it after reversing
+
+```js
+const str = "JavaScript is awesome"
+let reversedString = "";
+for(let i = 0; i < str.length; i++){
+ reversedString = str.charAt(i) + reversedString;
+}
+
+reversedString; // "emosewa si tpircSavaJ"
+```
+
+```js
+const str = "JavaScript is awesome";
+str.split("").reverse().join(""); // "emosewa si tpircSavaJ"
+```
+
+###### Notes
+The string can be tested if it is __palindrome__, by comparing the actual string with the reversed string
+
+###### References
+- https://www.freecodecamp.org/news/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb/
+
+
+
+
+#### Q5
+### Write a program to reverse a string by words. Also show the reverse of each words in place
+
+- The string can be reversed by words, by splitting the string with spaces and joining them back after reverse
+- If the the letters in each word have to be reversed, the string reversal procedure has to be followed after breaking the string with spaces
+
+```js
+const str = "JavaScript is awesome";
+str.split(" ").reverse().join(" "); // "awesome is JavaScript"
+```
+
+```js
+const str = "JavaScript is awesome";
+str.split(" ").map(val => val.split("").reverse().join("")).join(" "); // "tpircSavaJ si emosewa"
+```
+
+
+
+#### Q6
+### Write a program to reverse a given integer number
+
+- The remainder of the number can be fetched and the number can be divided by 10 to remvoe the the digit in loop till number becomes 0
+- A simple approach to reverse a number could also be to convert it in to a string and then reverse it
+
+```js
+let num = 3849;
+
+let reversedNum = 0;
+while(num !== 0){
+ reversedNum = reversedNum * 10 + num % 10;
+ num = Math.floor(num / 10);
+}
+
+reversedNum; // 9483
+```
+
+```js
+let num = 3849;
+
+let numStr = String(num);
++numStr.split("").reverse().join(""); // 9483
+```
+
+
+
+#### Q7
+### Write a code to replace all the spaces of the string with underscores
+
+- The string can be split using the space character and can be joined back with underscore to replace all the spaces with strings
+- `replaceAll` is the inbuilt String function on prototype which can be used to replace a string with another string
+
+```js
+str.split(" ").join("_");
+```
+
+```js
+str.replaceAll(" ", "_");
+```
+
+###### Notes
+`replace` is also an inbuilt String function on prototype which can be used to replace the 1st occurence of the string with another string
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
+
+
+
+#### Q8
+### Write a function which can convert the time input given in 12 hours format to 24 hours format
+```js
+// Example
+convertTo24HrsFormat('12:10AM'); // 00:10
+convertTo24HrsFormat('5:49AM'); // 05:49
+convertTo24HrsFormat('12:10PM'); // 12:10
+convertTo24HrsFormat('01:10PM'); // 13:10
+convertTo24HrsFormat('10:10PM'); // 22:10
+```
+
+- The check for 'AM' and 'PM' can be verified using `endsWith` String method
+- An extra 0 would be needed if the hours have single digit
+
+```js
+function convertTo24HrsFormat(timeText) {
+ var timeTextLower = timeText.toLowerCase();
+
+ if (timeTextLower.endsWith('am')) {
+ let [hours, mins] = timeTextLower.split(':');
+ hours = hours == 12 ? '0' : hours;
+ return hours.padStart(2, 0) + ':' + Number.parseInt(mins);
+ }
+ // 12 o clock is the special case to be handled both for AM and PM
+ else if (timeTextLower.endsWith('pm')) {
+ let [hours, mins] = timeTextLower.split(':');
+ hours = hours == 12 ? hours : +hours + 12;
+ return hours + ':' + Number.parseInt(mins);
+ }
+}
+```
+
+###### Notes
+Conversion of string to lowerCase helps in case insensitive comparision
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
+
+
+
+#### Q9
+### Write a function which accepts a string argument and returns the count of characters between the first and last character 'X'
+```js
+// Example
+getTheGapX('XeroX'); // 4
+getTheGapX('Xamarin'); // -1 (If there is only single character 'X')
+getTheGapX('JavaScript'); // -1 (If there is no character 'X')
+getTheGapX("F(X) !== G(X) !== F(X)"); // 18
+```
+
+- `indexOf` and `lastIndexOf` are the methods on String which returns the position of the given string in the input string from start and end respectively
+- If the match is not found, these methods return -1
+
+```js
+function getTheGapX(str) {
+ if (!str.includes('X')) {
+ return -1;
+ }
+
+ const firstIndex = str.indexOf('X');
+ const lastIndex = str.lastIndexOf('X');
+ return firstIndex === lastIndex ? -1 : lastIndex - firstIndex;
+}
+```
+
+
+
+#### Q10
+### Write a function to truncate a string to a certain number of letters
+```js
+// Example
+truncateString("JavaScript", 7) // "Java..."
+truncateString("JS is fun", 12) // "JS is fun"
+truncateString("JS is funny", 12) // "JS is fun..."
+```
+
+- Text can be truncated by fetching the substring from start till the count of characters
+- `substr` methods of String can be used to fetch the part of the string
+
+```js
+function truncateString(str, charCount) {
+ if (str.length > charCount) {
+ return str.substr(0, charCount - 3) + '...';
+ } else {
+ return str;
+ }
+}
+```
+
+
+
+#### Q11
+### Write a code to truncate a string to a certain number of words
+
+- The string can be broken in to words array and then `slice` method of array can be used to get the number of words which will then be joined back
+
+```js
+const str = 'JavaScript is simple but not easy to master';
+const wordLimit = 3;
+
+str.split(' ').slice(0, wordLimit).join(' '); // "JavaScript is simple"
+```
+
+
+
+#### Q12
+### Create a regular expression to validate if the given input is valid Indian mobile number or not
+```js
+// Example
+validateMobile('+919876543210'); // true
+validateMobile('+91 9876543210'); // true
+validateMobile('09876543210'); // true
+validateMobile('9876543210'); // true
+validateMobile('99876543210'); // false
+```
+
+- Regular expression check has to have an optional +91 or 0 in the beginning, then an optional space and 10 digits
+- `test` method of regular expression can be used to validate if the mobile number pattern matches or not
+
+```js
+function validateMobile(str) {
+ const regexMobile = /^(\+91|0)?\s?\d{10}$/;
+ return regexMobile.test(str);
+}
+```
+
+```js
+function validateMobile(str) {
+ const regexMobile = /^(\+91|0)?\s?\d{10}$/;
+ return str.match(regexMobile) !== null;
+}
+```
+
+###### Notes
+String has method `match` which returns array of matches or null
+
+
+
+#### Q13
+### Write a function which returns a list of elements which contains at least one character as digit
+```js
+// Example
+numInStr(['1a', 'a', '2b', 'b'])); // ['1a', '2b']
+numInStr(['abc', 'abc10'])); // ['abc10']
+numInStr(['abc', 'ab10c', 'a10bc', 'bcd'])); // ['ab10c', 'a10bc']
+numInStr(['this is a test', 'test1'])); // ['test1']
+```
+
+- A test for digit after looping through the array would give the list of values having at least one digit string
+
+```js
+function numInStr(mixArray){
+ return mixArray.filter((value) => {
+ return /[0-9]/.test(value);
+ });
+}
+```
+
+
+
+#### Q14
+### Write a function which checks if a given search text is present either in the beginning of the first name or the second name
+```js
+// Example
+validateName('Nedson PETER', "pet"); // true
+validateName('Peter Parker', "pet"); // true
+validateName('Speter parker', "pet"); // false
+validateName('John Doe Peter', "pet"); // false
+```
+
+- The function can be designed to accept the name and the search text
+- Regular expression can be designed to validate if the name has search text the beginning of first or second name
+
+```js
+function validateName(str, searchText) {
+ const regex = new RegExp("^(\\w*\\s)?" + searchText + "\\w*?", "i");
+ return regex.test(str);
+}
+```
+
+###### Notes
+Case insensitive match is happening for the search text in the string represented by the argument "i" for the regular expression
+
+
+
+#### Q15
+### Write a function to chop a string into chunks of a given length and return it as array
+```js
+// Example
+stringChop('JavaScript'); // ["JavaScript"]
+stringChop('JavaScript', 2); // ["Ja", "va", "Sc", "ri", "pt"]
+stringChop('JavaScript', 3); // ["Jav", "aSc", "rip", "t"]
+```
+
+- String can be chopped using `slice` method of String
+- Regular expression can also be used effectively to this operation
+
+```js
+function stringChop(str, size = str.length) {
+ const arr = [];
+ let i = 0;
+ while (i < str.length) {
+ arr.push(str.slice(i, i + size));
+ i = i + size;
+ }
+ return arr;
+}
+```
+
+```js
+function stringChop(str, size = str.length) {
+ return str.match(new RegExp('.{1,' + size + '}', 'g'));
+}
+```
+
+###### References
+- https://www.tutorialspoint.com/how-to-split-large-string-in-to-n-size-chunks-in-javascript
+
+
+
+#### Q16
+### Write a code to remove all the vowels from a given string
+
+- `replace` method on String accepts a string or regex as the argument
+
+```js
+const str = "I love JavaScript";
+str.replace(/[aeiou]/gi, ''); // _lv_JvScrpt
+```
+
+###### References
+- https://medium.com/better-programming/how-to-remove-vowels-from-a-string-in-javascript-fbed6e3a438e
+
+
+
+#### Q17
+### Create a function which returns random hex color code
+
+- The color code is popularly represented in hexadecimal format for RGB colors
+- The minimum value for the color is '#000000' and maximum is '#FFFFFF'
+
+```js
+function getGetHEXColorCode() {
+ const rValue = Math.round(0xFF * Math.random()).toString(16).padStart(2, '0');
+ const gValue = Math.round(0xFF * Math.random()).toString(16).padStart(2, '0');
+ const bValue = Math.round(0xFF * Math.random()).toString(16).padStart(2, '0');
+ return '#' + rValue + gValue + bValue;
+}
+```
+
+###### Notes
+`toString` method on String takes optional parameter which converts converts to the specified base before converting to string
+
+###### References
+- https://css-tricks.com/snippets/javascript/random-hex-color/
+
+
+
+#### Q18
+### Write a function which accepts two valid dates and returns the difference between them as number of days
+
+- The difference between 2 dates in JavaScript will give the time difference in milliseconds
+- Time difference can be converted in to days by dividing the 24Hrs time in milliseconds
+
+```js
+const DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
+
+function getDaysBetweenDates(dateText1, dateText2) {
+ const date1 = new Date(dateText1);
+ const date2 = new Date(dateText2);
+ const diffTime = Math.abs(date2 - date1);
+ const diffDays = Math.ceil(diffTime / DAY_IN_MILLISECONDS);
+ return diffDays;
+}
+
+getDaysBetweenDates('10/15/2020', '12/1/2020'); // 47
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
+
+
+
+[[↑] Back to top](#home)
diff --git a/challenges/primitives-concepts.md b/challenges/primitives-concepts.md
new file mode 100644
index 0000000..d8c363b
--- /dev/null
+++ b/challenges/primitives-concepts.md
@@ -0,0 +1,448 @@
+
+
+## JavaScript interview code challenges on Primitives - concepts
+
+1. [Show the usage of `typeof` operator on different types of values](#Q1)
+1. [Show the different ways of concatenating numbers and strings](#Q2)
+1. [Show the conversion from number to string and vice versa](#Q3)
+1. [Write a code to operate on integer numbers outside the range of numbers in JavaScript](#Q4)
+1. [Show the usage of `||`, `&&`, `??` and `!!` with code examples](#Q5)
+1. [Show the frequently and commonly used methods available on `Number` object with coding examples](#Q6)
+1. [Write the polyfill for `Number.isNaN`](#Q7)
+1. [Show the frequently and commonly used methods available on `Math` object with coding examples](#Q8)
+1. [How can we solve the problem of comparision of 0.1 + 0.2 with 0.3 where `===` operator fails](#Q9)
+1. [Write a code to iterate over a string](#Q10)
+1. [Show the creation of Regular Expression in JavaScript](#Q11)
+1. [Show the usage of template literals, expression interpolation and tagged templates](#Q12)
+1. [Write a code to show the working of `try...catch...finally`](#Q13)
+1. [Show the creation and usage of `symbol` with code](#Q14)
+
+---
+
+#### Q1
+### Show the usage of `typeof` operator on different types of values
+
+- The `typeof` operator returns a string indicating the type of the operand
+
+```js
+typeof 50 // "number"
+typeof "text" // "string"
+typeof true // "boolean"
+typeof undefined // "undefined"
+typeof function(){} // "function"
+typeof 10n // "bigint"
+typeof Symbol() // "symbol"
+typeof [1, 2] // "object"
+typeof {} // "object"
+
+typeof NaN // "number" (NaN is Not a Number)
+typeof undeclaredVar // "undefined" (undeclaredVariable is never declared)
+typeof Infinity // "number" (Infinity, -Infinity, -0 are all valid numbers in JavaScript)
+typeof null // "object" (This stands since the beginning of JavaScript)
+typeof /regex/ // "object" (regular expressions start and end with '/' in literal form)
+```
+
+###### Notes
+Arrays and functions are sub type of objects
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
+
+
+
+#### Q2
+### Show the different ways of concatenating numbers and strings
+
+- Concatenation of strings and numbers is a common practical use case
+
+```js
+// numbers and strings
+1 + '2'; // 12
+1 + 2 + '3'; // 33
+1 + 2 + '3' + '4'; // 334
+1 + 'One'; // 1One
+
+// strings and numbers
+'1' + 2; // 12
+'1' + '2' + 3; // 123
+'1' + '2' + 3 + 4; // 1234
+'1' + '2' + (3 + 4); // 127
+'One' + 1; // One1
+
+// mix of string and numbers
+1 + 2 + '3' + '4' + 5 + 6; // 33456
+1 + 2 + '3' + '4' + (5 + 6); // 33411
+'1' + '2' + (3 + 4) + 5 + '6'; // 12756
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
+
+
+
+#### Q3
+### Show the conversion from number to string and vice versa
+
+- Conversion between numbers and strings is a common practical use case
+
+```js
+// number to string conversion
+const num = 12;
+
+String(num); // "12"
+num.toString() // "12"
+num + ""; // "12"
+```
+
+```js
+// string to number conversion
+const str = "12";
+
+Number(str); // 12
++str // 12
+parseInt(str) // 12
+```
+
+###### Notes
+If the number is floating, `parseFloat` can be used. `parseInt` and `parseFloat` are the methods present on the `Number` object also
+
+###### References
+- https://javascript.info/type-conversions
+
+
+
+#### Q4
+### Write a code to operate on integer numbers outside the range of numbers in JavaScript
+
+- `BigInt` is a datatype in JavaScript which facilitates the mathematical opertions on huge value of integer number
+- It is represented by a suffix 'n' for number value
+
+```js
+// assignment of big integers
+const bigNum1 = 1526688934595n, bigNum2 = 256489246848n, num3 = 1562365;
+
+const bigSum = bigNum1 + bigNum2;
+const bigDiff = bigNum1 - bigNum2;
+const total = bigNum1 + bigNum2 + BigInt(num3);
+```
+
+###### Notes
+The big integers cannot be operated directly with normal number datatype. `10n + 20` is not allowed
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
+
+
+
+#### Q5
+### Show the usage of `||`, `&&`, `??` and `!!` with code examples
+
+- The __logical OR__ (||) operator for a set of operands is true if and only if one or more of its operands is true
+- The __logical AND__ (&&) operator for a set of operands is true if and only if all of its operands are true
+- The __nullish coalescing operator__ (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand
+- The __double NOT__ (!!) operator used to explicitly force the conversion of any value to the corresponding boolean primitive
+
+```js
+const num1 = 10, num2 = 20;
+
+true || false; // true
+false || false; // false
+false || num1; // 10
+0 || num2; // 20
+"text" || true // "text"
+num1 > 0 || num2 < 0 // true
+```
+
+```js
+const num1 = 10, num2 = 20;
+
+true && true; // true
+true && false; // false
+true && num1; // 10
+num1 && num2; // 20
+"text" && (num1 + num2) // 30
+num1 > 0 && num2 < 0 // false
+```
+
+```js
+undefined ?? 10; // 10
+null ?? 20; // 20
+false ?? num1; // false
+0 ?? num2; // 0
+```
+
+```js
+!!10; // true
+!!{}; // true
+!!""; // false
+!!0; // false
+```
+
+###### Notes
+It is not possible to combine both the AND (&&) and OR operators (||) directly with ??
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
+- https://developer.cdn.mozilla.net/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT
+
+
+
+#### Q6
+### Show the frequently and commonly used methods available on `Number` object with coding examples
+
+- `isInteger` is used to check if the given number is integer or not
+- `parseInt` is used to convert a given value in to integer
+- `parseFloat` is used to convert a given value in to floating number
+- `isNan` is used to check if the given value is NaN or no
+- `toFixed` is used to limit the number of digits after the decimal place
+- `toPrecision` is used to limit the total number of digits to represent the number
+
+```js
+Number.isInteger(1.5); // false
+Number.isInteger(-15); // true
+
+Number.parseInt('5.8'); // 5
+Number.parseInt('123x') // 123
+
+Number.parseFloat('5.86'); // 5.86
+Number.parseFloat('-12.69x'); // -12.69
+
+Number.isNaN(NaN); // true
+Number.isNaN("text" - 10); // true
+Number.isNaN("text"); // false
+```
+
+```js
+56.369.toFixed(2); // 56.37
+59..toFixed(3); // 59.000
+
+32.458.toPrecision('3'); // 32.5
+98.1.toPrecision(1); // 9e+1
+```
+
+###### Notes
+`NaN` is special type of number and this value is results by the invalid mathematical operations such as substraction of number and text
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
+
+
+
+#### Q7
+### Write the polyfill for `Number.isNaN`
+
+- A polyfill is a piece of code used to provide modern functionality on older browsers that do not natively support it
+- `NaN` is the only value which is not equal to itself and hence comparision operator cannot be used directly to check if a value is `NaN`
+
+```js
+Number.isNaN = Number.isNaN || function isNaN(input) {
+ return typeof input === 'number' && input !== input;
+}
+```
+
+###### Notes
+Even though the name says _Not a Number_, it is of type "number"
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
+
+
+
+#### Q8
+### Show the frequently and commonly used methods available on `Math` object with coding examples
+
+- `abs` is used to get the absolute value of the given number
+- `floor` is used to get the greatest integer smaller than or equal to the given number
+- `ceil` is used to get the smallest integer greater than or equal to the given number
+- `round` is used to round the given number to the nearest integer.
+- `max` is used to get the largest of zero or more numbers
+- `min` is used to get the smallest of zero or more numbers
+- `sqrt` is used to calculate the square root of the given number
+- `pow` is used to calculate the power base on inputs
+- `trunc` is used to limit the total number of digits to represent the number (method is present on prototype of `Number`)
+
+```js
+Math.abs(-5)); // 5
+Math.floor(1.6)); // 1
+Math.ceil(2.4)); // 3
+Math.round(3.8)); // 4
+Math.max(-4, 5, 6)); // 6
+Math.min(-7, -2, 3)); // -7
+Math.sqrt(64)); // 8
+Math.pow(5, 3)); // 125
+Math.trunc(-6.3)); // -6
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math
+
+
+
+#### Q9
+### How can we solve the problem of comparision of 0.1 + 0.2 with 0.3 where `===` operator fails
+
+- The addition of 0.1 and 0.2 will result in to 0.30000000000000004 and the comparision with 0.3 fails
+- `Number.epsilon` is 2-52, which can be used to verify if this decimal values are matching
+
+```js
+0.1 + 0.2 - 0.3 < Number.EPSILON // true
+```
+
+###### References
+- https://www.programiz.com/javascript/library/number/epsilon
+
+
+
+#### Q10
+### Write a code to iterate over a string
+
+- String can be traversed using its string index or value as string can act like an iterable
+
+```js
+for(let i =0; i < str.length; i++){
+ console.log(str.charAt(i));
+}
+```
+
+```js
+for(let index in str){
+ console.log(str[index]);
+}
+```
+
+```js
+for(let value of str){
+ console.log(value);
+}
+```
+
+```js
+[...str].forEach((value) => console.log(value));
+```
+
+###### References
+- https://medium.com/better-programming/how-to-iterate-through-strings-in-javascript-65c51bb3ace5
+
+
+
+#### Q11
+### Show the creation of Regular Expression in JavaScript
+
+- Regular expressions are patterns used to match character combinations in strings
+- Regular expressions can be created using literal form or constructor form
+- Constructor form accepts regular expression as the first argument and flags as the 2nd argument
+- Literal form is simple which takes regular expression and flags in a single expression
+
+```js
+// literal form
+let re = /ab+c/g;
+```
+
+```js
+// constructor form
+let re = new RegExp('ab+c', 'g');
+```
+
+###### Notes
+In JavaScript, regular expressions are objects
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
+
+
+
+#### Q12
+### Show the usage of template literals with expression interpolation and tagged templates
+
+- Template literals are string literals allowing embedded expressions and support multi lines
+- Template literals are enclosed by the backtick \`
+- Tagged templates allow to parse template literals with a function which gets array of strings and expressions as arguments
+
+```js
+// Template literals with expression interpolation
+const num1 = 10, num2 = 20;
+`The sum of ${num1} and ${num2} is ${num1 + num2}`; // The sum of 10 and 20 is 30
+```
+
+```js
+// Tagged templates
+let person = 'John';
+let membership = [1, 3];
+
+function myTag(strings, person, membership) {
+ let communities = ['Java', 'JavaScript', 'TypeScript', 'HTML', 'CSS']
+
+ let str0 = strings[0]; // "Note:"
+ let str1 = strings[1]; // "is a member of following communities:"
+
+ let personCommunities = membership.map(index => communities[index])
+ return `${str0}${person}${str1}${personCommunities}`;
+}
+
+myTag`Note: ${person} is a member of following communities: ${membership}`; // Note: John is a member of following communities: JavaScript,HTML
+```
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
+
+
+
+#### Q13
+### Write a code to show the working of `try...catch...finally`
+
+- The `try` statement consists of a try-block, which contains one or more statements. At least one catch-block, or a finally-block, must be present
+- The exceptions and errors from try block are caught in catch block
+
+```js
+try {
+ // Below statement will throw an Error
+ callAPI();
+} catch (error) {
+ // Create a new error and throw
+ throw new Error(error); // ReferenceError: callAPI is not defined
+} finally {
+ console.log('I will execute no matter what happened in try or catch');
+}
+```
+
+###### Notes
+- `try` can be chained with `catch` block or `finally` block
+- `try..catch` only works synchronously and for runtime errors
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
+
+
+
+#### Q14
+### Show the creation and usage of `symbol` with code
+
+- A "symbol" represents a unique identifier
+- `Symbol.for` method searches for existing symbols in a runtime-wide symbol registry returns the same. If not found, creates a new Symbol
+- `Symbol.keyFor` method retrieves the name of the symbol
+
+```js
+// new symbol
+let symId = Symbol("id");
+
+// global symbol
+let symUsername = Symbol.for("username");
+
+// get name by symbol
+Symbol.keyFor(symUsername); // username
+```
+
+###### Notes
+Symbols are skipped by for…in
+
+###### References
+- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
+- https://javascript.info/symbol
+
+
+
+[[↑] Back to top](#home)
diff --git a/challenges/primitives.md b/challenges/primitives.md
deleted file mode 100644
index 25f990d..0000000
--- a/challenges/primitives.md
+++ /dev/null
@@ -1,909 +0,0 @@
-
-
-## JavaScript interview code challenges on Primitives
-
-1. [Show the usage of `typeof` operator on different types of values](#Q1)
-2. [Show the different ways of concatenating numbers and strings](#Q2)
-3. [Swap 2 integers present in variables num1 and num2 without using temporary variable](#Q3)
-4. [Show the conversion from number to string and vice versa](#Q4)
-5. [Write a code to operate on integer numbers outside the range of numbers in JavaScript](#Q5)
-6. [Show the usage of `||`, `&&`, `??` and `!!` with code examples](#Q6)
-7. [Show the frequently and commonly used methods available on `Number` object with coding examples](#Q7)
-8. [Write the polyfill for `Number.isNaN`](#Q8)
-9. [Show the frequently and commonly used methods available on `Math` object with coding examples](#Q9)
-10. [Write a function which returns true if given value of number is an integer without using any inbuilt functions](#Q10)
-11. [Create a function which returns a random number in the given range of values both inclusive](#Q11)
-12. [How can we solve the problem of comparision of 0.1 + 0.2 with 0.3 where `===` operator fails](#Q12)
-13. [Write a code to iterate over a string](#Q13)
-14. [Write a program to reverse a string](#Q14)
-15. [Write a program to reverse a string by words. Also show the reverse of each words in place](#Q15)
-16. [Write a program to reverse a given integer number](#Q16)
-17. [Write a code to replace all the spaces of the string with underscores](#Q17)
-18. [Write a function which can convert the time input given in 12 hours format to 24 hours format](#Q18)
-19. [Write a function which accepts a string argument and returns the count of characters between the first and last character 'X'](#Q19)
-20. [Write a function to truncate a string to a certain number of letters](#Q20)
-21. [Write a code to truncate a string to a certain number of words](#Q21)
-22. [Show the creation of Regular Expression in JavaScript](#Q22)
-23. [Create a regular expression to validate if the given input is valid Indian mobile number or not](#Q23)
-24. [Write a function which returns a list of elements which contains at least one character as digit](#Q24)
-25. [Write a function which checks if a given search text is present either in the beginning of the first name or the second name](#Q25)
-26. [Write a function to chop a string into chunks of a given length and return it as array](#Q26)
-27. [Write a code to remove all the vowels from a given string](#Q27)
-28. [Create a function which returns random hex color code](#Q28)
-29. [Write a function which accepts two valid dates and returns the difference between them as number of days](#Q29)
-30. [Show the usage of template literals, expression interpolation and tagged templates](#Q30)
-31. [Write a code to show the working of `try...catch...finally`](#Q31)
-32. [Show the creation and usage of `symbol` with code](#Q32)
-
----
-
-#### Q1
-### Show the usage of `typeof` operator on different types of values
-
-- The `typeof` operator returns a string indicating the type of the operand
-
-```js
-typeof 50 // "number"
-typeof "text" // "string"
-typeof true // "boolean"
-typeof undefined // "undefined"
-typeof function(){} // "function"
-typeof 10n // "bigint"
-typeof Symbol() // "symbol"
-typeof [1, 2] // "object"
-typeof {} // "object"
-
-typeof NaN // "number" (NaN is Not a Number)
-typeof undeclaredVar // "undefined" (undeclaredVariable is never declared)
-typeof Infinity // "number" (Infinity, -Infinity, -0 are all valid numbers in JavaScript)
-typeof null // "object" (This stands since the beginning of JavaScript)
-typeof /regex/ // "object" (regular expressions start and end with '/' in literal form)
-```
-
-###### Notes
-Arrays and functions are sub type of objects
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
-
-
-
-#### Q2
-### Show the different ways of concatenating numbers and strings
-
-- Concatenation of strings and numbers is a common practical use case
-
-```js
-// numbers and strings
-1 + '2'; // 12
-1 + 2 + '3'; // 33
-1 + 2 + '3' + '4'; // 334
-1 + 'One'; // 1One
-
-// strings and numbers
-'1' + 2; // 12
-'1' + '2' + 3; // 123
-'1' + '2' + 3 + 4; // 1234
-'1' + '2' + (3 + 4); // 127
-'One' + 1; // One1
-
-// mix of string and numbers
-1 + 2 + '3' + '4' + 5 + 6; // 33456
-1 + 2 + '3' + '4' + (5 + 6); // 33411
-'1' + '2' + (3 + 4) + 5 + '6'; // 12756
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
-
-
-
-#### Q3
-### Swap 2 integers present in variables num1 and num2 without using temporary variable
-
-- The swapping of 2 variables is possible with simple Destructuring assignment using array
-- Traditional approach of swapping by using the given variables is also achievable
-
-```js
-let num1 = 10, num2 = 20;
-[num1, num2] = [num2, num1];
-```
-
-```js
-let num1 = 10, num2 = 20;
-num1 = num1 + num2;
-num2 = num1 - num2;
-num1 = num1 - num2;
-```
-
-###### Notes
-2nd solution can fail due to overflow of number range if the numbers are very big
-
-
-
-#### Q4
-### Show the conversion from number to string and vice versa
-
-- Conversion between numbers and strings is a common practical use case
-
-```js
-// number to string conversion
-const num = 12;
-
-String(num); // "12"
-num.toString() // "12"
-num + ""; // "12"
-```
-
-```js
-// string to number conversion
-const str = "12";
-
-Number(str); // 12
-+str // 12
-parseInt(str) // 12
-```
-
-###### Notes
-If the number is floating, `parseFloat` can be used. `parseInt` and `parseFloat` are the methods present on the `Number` object also
-
-###### References
-- https://javascript.info/type-conversions
-
-
-
-#### Q5
-### Write a code to operate on integer numbers outside the range of numbers in JavaScript
-
-- `BigInt` is a datatype in JavaScript which facilitates the mathematical opertions on huge value of integer number
-- It is represented by a suffix 'n' for number value
-
-```js
-// assignment of big integers
-const bigNum1 = 1526688934595n, bigNum2 = 256489246848n, num3 = 1562365;
-
-const bigSum = bigNum1 + bigNum2;
-const bigDiff = bigNum1 - bigNum2;
-const total = bigNum1 + bigNum2 + BigInt(num3);
-```
-
-###### Notes
-The big integers cannot be operated directly with normal number datatype. `10n + 20` is not allowed
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
-
-
-
-#### Q6
-### Show the usage of `||`, `&&`, `??` and `!!` with code examples
-
-- The __logical OR__ (||) operator for a set of operands is true if and only if one or more of its operands is true
-- The __logical AND__ (&&) operator for a set of operands is true if and only if all of its operands are true
-- The __nullish coalescing operator__ (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand
-- The __double NOT__ (!!) operator used to explicitly force the conversion of any value to the corresponding boolean primitive
-
-```js
-const num1 = 10, num2 = 20;
-
-true || false; // true
-false || false; // false
-false || num1; // 10
-0 || num2; // 20
-"text" || true // "text"
-num1 > 0 || num2 < 0 // true
-```
-
-```js
-const num1 = 10, num2 = 20;
-
-true && true; // true
-true && false; // false
-true && num1; // 10
-num1 && num2; // 20
-"text" && (num1 + num2) // 30
-num1 > 0 && num2 < 0 // false
-```
-
-```js
-undefined ?? 10; // 10
-null ?? 20; // 20
-false ?? num1; // false
-0 ?? num2; // 0
-```
-
-```js
-!!10; // true
-!!{}; // true
-!!""; // false
-!!0; // false
-```
-
-###### Notes
-It is not possible to combine both the AND (&&) and OR operators (||) directly with ??
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
-- https://developer.cdn.mozilla.net/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT
-
-
-
-#### Q7
-### Show the frequently and commonly used methods available on `Number` object with coding examples
-
-- `isInteger` is used to check if the given number is integer or not
-- `parseInt` is used to convert a given value in to integer
-- `parseFloat` is used to convert a given value in to floating number
-- `isNan` is used to check if the given value is NaN or no
-- `toFixed` is used to limit the number of digits after the decimal place
-- `toPrecision` is used to limit the total number of digits to represent the number
-
-```js
-Number.isInteger(1.5); // false
-Number.isInteger(-15); // true
-
-Number.parseInt('5.8'); // 5
-Number.parseInt('123x') // 123
-
-Number.parseFloat('5.86'); // 5.86
-Number.parseFloat('-12.69x'); // -12.69
-
-Number.isNaN(NaN); // true
-Number.isNaN("text" - 10); // true
-Number.isNaN("text"); // false
-```
-
-```js
-56.369.toFixed(2); // 56.37
-59..toFixed(3); // 59.000
-
-32.458.toPrecision('3'); // 32.5
-98.1.toPrecision(1); // 9e+1
-```
-
-###### Notes
-`NaN` is special type of number and this value is results by the invalid mathematical operations such as substraction of number and text
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
-
-
-
-#### Q8
-### Write the polyfill for `Number.isNaN`
-
-- A polyfill is a piece of code used to provide modern functionality on older browsers that do not natively support it
-- `NaN` is the only value which is not equal to itself and hence comparision operator cannot be used directly to check if a value is `NaN`
-
-```js
-Number.isNaN = Number.isNaN || function isNaN(input) {
- return typeof input === 'number' && input !== input;
-}
-```
-
-###### Notes
-Even though the name says _Not a Number_, it is of type "number"
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
-
-
-
-#### Q9
-### Show the frequently and commonly used methods available on `Math` object with coding examples
-
-- `abs` is used to get the absolute value of the given number
-- `floor` is used to get the greatest integer smaller than or equal to the given number
-- `ceil` is used to get the smallest integer greater than or equal to the given number
-- `round` is used to round the given number to the nearest integer.
-- `max` is used to get the largest of zero or more numbers
-- `min` is used to get the smallest of zero or more numbers
-- `sqrt` is used to calculate the square root of the given number
-- `pow` is used to calculate the power base on inputs
-- `trunc` is used to limit the total number of digits to represent the number (method is present on prototype of `Number`)
-
-```js
-Math.abs(-5)); // 5
-Math.floor(1.6)); // 1
-Math.ceil(2.4)); // 3
-Math.round(3.8)); // 4
-Math.max(-4, 5, 6)); // 6
-Math.min(-7, -2, 3)); // -7
-Math.sqrt(64)); // 8
-Math.pow(5, 3)); // 125
-Math.trunc(-6.3)); // -6
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math
-
-
-
-#### Q10
-### Write a function which returns true if given value of number is an integer without using any inbuilt functions
-```js
-// Example
-isInt(4.0); // true
-isInt(12.2); // false
-isInt(0.3); // false
-```
-- Modulo operator can be used to check if there is a remainder left when divided by 1
-
-```js
-function isInt(value){
- return value % 1 === 0;
-}
-```
-
-
-
-#### Q11
-### Create a function which returns a random number in the given range of values both inclusive
-
-- `Math.random` function returns a floating-point, pseudo-random number between 0 (inclusive) and 1 (exclusive)
-
-```js
-function randomNumberGeneratorInRange(rangeStart, rangeEnd){
- return rangeStart + Math.round(Math.random() * (rangeEnd - rangeStart));
-}
-
-randomNumberGeneratorInRange(10, 50); // 12
-```
-
-###### Notes
-Usage of `Math.round` depends on the logic used to accomplish the requirement
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
-
-
-
-#### Q12
-### How can we solve the problem of comparision of 0.1 + 0.2 with 0.3 where `===` operator fails
-
-- The addition of 0.1 and 0.2 will result in to 0.30000000000000004 and the comparision with 0.3 fails
-- `Number.epsilon` is 2-52, which can be used to verify if this decimal values are matching
-
-```js
-0.1 + 0.2 - 0.3 < Number.EPSILON // true
-```
-
-###### References
-- https://www.programiz.com/javascript/library/number/epsilon
-
-
-
-#### Q13
-### Write a code to iterate over a string
-
-- String can be traversed using its string index or value as string can act like an iterable
-
-```js
-for(let i =0; i < str.length; i++){
- console.log(str.charAt(i));
-}
-```
-
-```js
-for(let index in str){
- console.log(str[index]);
-}
-```
-
-```js
-for(let value of str){
- console.log(value);
-}
-```
-
-```js
-[...str].forEach((value) => console.log(value));
-```
-
-###### References
-- https://medium.com/better-programming/how-to-iterate-through-strings-in-javascript-65c51bb3ace5
-
-
-
-#### Q14
-### Write a program to reverse a string
-
-- String can be reversed by iterating it and storing it in reverse order
-- String can also be reversed by converting it to array, then joining it after reversing
-
-```js
-const str = "JavaScript is awesome"
-let reversedString = "";
-for(let i = 0; i < str.length; i++){
- reversedString = str.charAt(i) + reversedString;
-}
-
-reversedString; // "emosewa si tpircSavaJ"
-```
-
-```js
-const str = "JavaScript is awesome";
-str.split("").reverse().join(""); // "emosewa si tpircSavaJ"
-```
-
-###### Notes
-The string can be tested if it is __palindrome__, by comparing the actual string with the reversed string
-
-###### References
-- https://www.freecodecamp.org/news/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb/
-
-
-
-
-#### Q15
-### Write a program to reverse a string by words. Also show the reverse of each words in place
-
-- The string can be reversed by words, by splitting the string with spaces and joining them back after reverse
-- If the the letters in each word have to be reversed, the string reversal procedure has to be followed after breaking the string with spaces
-
-```js
-const str = "JavaScript is awesome";
-str.split(" ").reverse().join(" "); // "awesome is JavaScript"
-```
-
-```js
-const str = "JavaScript is awesome";
-str.split(" ").map(val => val.split("").reverse().join("")).join(" "); // "tpircSavaJ si emosewa"
-```
-
-
-
-#### Q16
-### Write a program to reverse a given integer number
-
-- The remainder of the number can be fetched and the number can be divided by 10 to remvoe the the digit in loop till number becomes 0
-- A simple approach to reverse a number could also be to convert it in to a string and then reverse it
-
-```js
-let num = 3849;
-
-let reversedNum = 0;
-while(num !== 0){
- reversedNum = reversedNum * 10 + num % 10;
- num = Math.floor(num / 10);
-}
-
-reversedNum; // 9483
-```
-
-```js
-let num = 3849;
-
-let numStr = String(num);
-+numStr.split("").reverse().join(""); // 9483
-```
-
-
-
-#### Q17
-### Write a code to replace all the spaces of the string with underscores
-
-- The string can be split using the space character and can be joined back with underscore to replace all the spaces with strings
-- `replaceAll` is the inbuilt String function on prototype which can be used to replace a string with another string
-
-```js
-str.split(" ").join("_");
-```
-
-```js
-str.replaceAll(" ", "_");
-```
-
-###### Notes
-`replace` is also an inbuilt String function on prototype which can be used to replace the 1st occurence of the string with another string
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
-
-
-
-#### Q18
-### Write a function which can convert the time input given in 12 hours format to 24 hours format
-```js
-// Example
-convertTo24HrsFormat('12:10AM'); // 00:10
-convertTo24HrsFormat('5:49AM'); // 05:49
-convertTo24HrsFormat('12:10PM'); // 12:10
-convertTo24HrsFormat('01:10PM'); // 13:10
-convertTo24HrsFormat('10:10PM'); // 22:10
-```
-
-- The check for 'AM' and 'PM' can be verified using `endsWith` String method
-- An extra 0 would be needed if the hours have single digit
-
-```js
-function convertTo24HrsFormat(timeText) {
- var timeTextLower = timeText.toLowerCase();
-
- if (timeTextLower.endsWith('am')) {
- let [hours, mins] = timeTextLower.split(':');
- hours = hours == 12 ? '0' : hours;
- return hours.padStart(2, 0) + ':' + Number.parseInt(mins);
- }
- // 12 o clock is the special case to be handled both for AM and PM
- else if (timeTextLower.endsWith('pm')) {
- let [hours, mins] = timeTextLower.split(':');
- hours = hours == 12 ? hours : +hours + 12;
- return hours + ':' + Number.parseInt(mins);
- }
-}
-```
-
-###### Notes
-Conversion of string to lowerCase helps in case insensitive comparision
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
-
-
-
-#### Q19
-### Write a function which accepts a string argument and returns the count of characters between the first and last character 'X'
-```js
-// Example
-getTheGapX('XeroX'); // 4
-getTheGapX('Xamarin'); // -1 (If there is only single character 'X')
-getTheGapX('JavaScript'); // -1 (If there is no character 'X')
-getTheGapX("F(X) !== G(X) !== F(X)"); // 18
-```
-
-- `indexOf` and `lastIndexOf` are the methods on String which returns the position of the given string in the input string from start and end respectively
-- If the match is not found, these methods return -1
-
-```js
-function getTheGapX(str) {
- if (!str.includes('X')) {
- return -1;
- }
-
- const firstIndex = str.indexOf('X');
- const lastIndex = str.lastIndexOf('X');
- return firstIndex === lastIndex ? -1 : lastIndex - firstIndex;
-}
-```
-
-
-
-#### Q20
-### Write a function to truncate a string to a certain number of letters
-```js
-// Example
-truncateString("JavaScript", 7) // "Java..."
-truncateString("JS is fun", 12) // "JS is fun"
-truncateString("JS is funny", 12) // "JS is fun..."
-```
-
-- Text can be truncated by fetching the substring from start till the count of characters
-- `substr` methods of String can be used to fetch the part of the string
-
-```js
-function truncateString(str, charCount) {
- if (str.length > charCount) {
- return str.substr(0, charCount - 3) + '...';
- } else {
- return str;
- }
-}
-```
-
-
-
-#### Q21
-### Write a code to truncate a string to a certain number of words
-
-- The string can be broken in to words array and then `slice` method of array can be used to get the number of words which will then be joined back
-
-```js
-const str = 'JavaScript is simple but not easy to master';
-const wordLimit = 3;
-
-str.split(' ').slice(0, wordLimit).join(' '); // "JavaScript is simple"
-```
-
-
-
-#### Q22
-### Show the creation of Regular Expression in JavaScript
-
-- Regular expressions are patterns used to match character combinations in strings
-- Regular expressions can be created using literal form or constructor form
-- Constructor form accepts regular expression as the first argument and flags as the 2nd argument
-- Literal form is simple which takes regular expression and flags in a single expression
-
-```js
-// literal form
-let re = /ab+c/g;
-```
-
-```js
-// constructor form
-let re = new RegExp('ab+c', 'g');
-```
-
-###### Notes
-In JavaScript, regular expressions are objects
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
-
-
-
-#### Q23
-### Create a regular expression to validate if the given input is valid Indian mobile number or not
-```js
-// Example
-validateMobile('+919876543210'); // true
-validateMobile('+91 9876543210'); // true
-validateMobile('09876543210'); // true
-validateMobile('9876543210'); // true
-validateMobile('99876543210'); // false
-```
-
-- Regular expression check has to have an optional +91 or 0 in the beginning, then an optional space and 10 digits
-- `test` method of regular expression can be used to validate if the mobile number pattern matches or not
-
-```js
-function validateMobile(str) {
- const regexMobile = /^(\+91|0)?\s?\d{10}$/;
- return regexMobile.test(str);
-}
-```
-
-```js
-function validateMobile(str) {
- const regexMobile = /^(\+91|0)?\s?\d{10}$/;
- return str.match(regexMobile) !== null;
-}
-```
-
-###### Notes
-String has method `match` which returns array of matches or null
-
-
-
-#### Q24
-### Write a function which returns a list of elements which contains at least one character as digit
-```js
-// Example
-numInStr(['1a', 'a', '2b', 'b'])); // ['1a', '2b']
-numInStr(['abc', 'abc10'])); // ['abc10']
-numInStr(['abc', 'ab10c', 'a10bc', 'bcd'])); // ['ab10c', 'a10bc']
-numInStr(['this is a test', 'test1'])); // ['test1']
-```
-
-- A test for digit after looping through the array would give the list of values having at least one digit string
-
-```js
-function numInStr(mixArray){
- return mixArray.filter((value) => {
- return /[0-9]/.test(value);
- });
-}
-```
-
-
-
-#### Q25
-### Write a function which checks if a given search text is present either in the beginning of the first name or the second name
-```js
-// Example
-validateName('Nedson PETER', "pet"); // true
-validateName('Peter Parker', "pet"); // true
-validateName('Speter parker', "pet"); // false
-validateName('John Doe Peter', "pet"); // false
-```
-
-- The function can be designed to accept the name and the search text
-- Regular expression can be designed to validate if the name has search text the beginning of first or second name
-
-```js
-function validateName(str, searchText) {
- const regex = new RegExp("^(\\w*\\s)?" + searchText + "\\w*?", "i");
- return regex.test(str);
-}
-```
-
-###### Notes
-Case insensitive match is happening for the search text in the string represented by the argument "i" for the regular expression
-
-
-
-#### Q26
-### Write a function to chop a string into chunks of a given length and return it as array
-```js
-// Example
-stringChop('JavaScript'); // ["JavaScript"]
-stringChop('JavaScript', 2); // ["Ja", "va", "Sc", "ri", "pt"]
-stringChop('JavaScript', 3); // ["Jav", "aSc", "rip", "t"]
-```
-
-- String can be chopped using `slice` method of String
-- Regular expression can also be used effectively to this operation
-
-```js
-function stringChop(str, size = str.length) {
- const arr = [];
- let i = 0;
- while (i < str.length) {
- arr.push(str.slice(i, i + size));
- i = i + size;
- }
- return arr;
-}
-```
-
-```js
-function stringChop(str, size = str.length) {
- return str.match(new RegExp('.{1,' + size + '}', 'g'));
-}
-```
-
-###### References
-- https://www.tutorialspoint.com/how-to-split-large-string-in-to-n-size-chunks-in-javascript
-
-
-
-#### Q27
-### Write a code to remove all the vowels from a given string
-
-- `replace` method on String accepts a string or regex as the argument
-
-```js
-const str = "I love JavaScript";
-str.replace(/[aeiou]/gi, ''); // _lv_JvScrpt
-```
-
-###### References
-- https://medium.com/better-programming/how-to-remove-vowels-from-a-string-in-javascript-fbed6e3a438e
-
-
-
-#### Q28
-### Create a function which returns random hex color code
-
-- The color code is popularly represented in hexadecimal format for RGB colors
-- The minimum value for the color is '#000000' and maximum is '#FFFFFF'
-
-```js
-function getGetHEXColorCode() {
- const rValue = Math.round(0xFF * Math.random()).toString(16).padStart(2, '0');
- const gValue = Math.round(0xFF * Math.random()).toString(16).padStart(2, '0');
- const bValue = Math.round(0xFF * Math.random()).toString(16).padStart(2, '0');
- return '#' + rValue + gValue + bValue;
-}
-```
-
-###### Notes
-`toString` method on String takes optional parameter which converts converts to the specified base before converting to string
-
-###### References
-- https://css-tricks.com/snippets/javascript/random-hex-color/
-
-
-
-#### Q29
-### Write a function which accepts two valid dates and returns the difference between them as number of days
-
-- The difference between 2 dates in JavaScript will give the time difference in milliseconds
-- Time difference can be converted in to days by dividing the 24Hrs time in milliseconds
-
-```js
-const DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
-
-function getDaysBetweenDates(dateText1, dateText2) {
- const date1 = new Date(dateText1);
- const date2 = new Date(dateText2);
- const diffTime = Math.abs(date2 - date1);
- const diffDays = Math.ceil(diffTime / DAY_IN_MILLISECONDS);
- return diffDays;
-}
-
-getDaysBetweenDates('10/15/2020', '12/1/2020'); // 47
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
-
-
-
-#### Q30
-### Show the usage of template literals with expression interpolation and tagged templates
-
-- Template literals are string literals allowing embedded expressions and support multi lines
-- Template literals are enclosed by the backtick \`
-- Tagged templates allow to parse template literals with a function which gets array of strings and expressions as arguments
-
-```js
-// Template literals with expression interpolation
-const num1 = 10, num2 = 20;
-`The sum of ${num1} and ${num2} is ${num1 + num2}`; // The sum of 10 and 20 is 30
-```
-
-```js
-// Tagged templates
-let person = 'John';
-let membership = [1, 3];
-
-function myTag(strings, person, membership) {
- let communities = ['Java', 'JavaScript', 'TypeScript', 'HTML', 'CSS']
-
- let str0 = strings[0]; // "Note:"
- let str1 = strings[1]; // "is a member of following communities:"
-
- let personCommunities = membership.map(index => communities[index])
- return `${str0}${person}${str1}${personCommunities}`;
-}
-
-myTag`Note: ${person} is a member of following communities: ${membership}`; // Note: John is a member of following communities: JavaScript,HTML
-```
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
-
-
-
-#### Q31
-### Write a code to show the working of `try...catch...finally`
-
-- The `try` statement consists of a try-block, which contains one or more statements. At least one catch-block, or a finally-block, must be present
-- The exceptions and errors from try block are caught in catch block
-
-```js
-try {
- // Below statement will throw an Error
- callAPI();
-} catch (error) {
- // Create a new error and throw
- throw new Error(error); // ReferenceError: callAPI is not defined
-} finally {
- console.log('I will execute no matter what happened in try or catch');
-}
-```
-
-###### Notes
-- `try` can be chained with `catch` block or `finally` block
-- `try..catch` only works synchronously and for runtime errors
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
-
-
-
-#### Q32
-### Show the creation and usage of `symbol` with code
-
-- A "symbol" represents a unique identifier
-- `Symbol.for` method searches for existing symbols in a runtime-wide symbol registry returns the same. If not found, creates a new Symbol
-- `Symbol.keyFor` method retrieves the name of the symbol
-
-```js
-// new symbol
-let symId = Symbol("id");
-
-// global symbol
-let symUsername = Symbol.for("username");
-
-// get name by symbol
-Symbol.keyFor(symUsername); // username
-```
-
-###### Notes
-Symbols are skipped by for…in
-
-###### References
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
-- https://javascript.info/symbol
-
-
-
-[[↑] Back to top](#home)