├── .gitignore ├── Array-Problems ├── array-complements.js ├── array-left-rotation-by-steps.js ├── array-of-Objects-mutate-formatting-Mongo-date-Performance.js ├── array-of-Objects-mutate-formatting-Mongo-date.js ├── array-of-Objects-mutate-simple.js ├── array-right-rotation-by-no-of-positions.js ├── find-closest-number-in-array.js ├── find-count-of-max-elements.js ├── find-length-of-integer-without-converting-to-string.js ├── find-min-max-of-after-popping-one-elem.js ├── flatten-Array-Deep-2.js ├── flatten-arr-of-objects-with-flat-package.js ├── flatten-arr-of-objects-with-lodash-flatMap-2.js ├── flatten-arr-of-objects-with-lodash-flatMap-GREAT-performance.js ├── flatten-arr-of-objects-with-lodash-flatMap-GREAT.js ├── flatten-arr-of-objects-with-lodash-merge.js ├── flatten-arr-of-objects-with-plain-JS-1.js ├── flatten_array.js ├── flatten_array_Deep.js ├── forEach-first-Principle-custom-callback.js ├── indexOf_manually_build.js ├── intersection-of-arrays.js ├── largest-numbers-from-subarray.js ├── map-first-Principle-custom-callback.js ├── max-repeated-num-in-array.js ├── max-repeating-element.js ├── misc_Array_Problems_JS-Cookbook.js ├── mongo-json-data-TEST.js ├── reduce_method_applications.js ├── reverseArray-Recursively.js ├── search-unknown-length-Array.js ├── shuffle_Array-1.js ├── shuffle_Array-2.js ├── tempCodeRunnerFile.js └── tiny-Array-probs │ ├── clone_Array.js │ └── returns-true-if-all-elemensts-true.js ├── ES6 ├── Destructuring_Geneal.md ├── calback-hell-resolved-with-promise.js ├── callback-hell-examples.js ├── create-class-in-ES6.js ├── destructuring.js ├── every-method-of-Array.js ├── fat-arrow-function.js ├── filter-implement-remove-duplicates.js ├── find-method.js ├── function-currying.js ├── map-Implementation-On-Objects.js ├── promise-basic-implementation.js ├── reduce-implementation.js ├── rest-spread-2.js ├── rest-spread.jpg ├── rest-spread.js ├── some-method-of-Array.js ├── this-in-ES6.js ├── this-in-ES6 │ ├── README.md │ ├── this-in-ES6.js │ ├── this-in-ES6_2.js │ └── this-in-ES6_3.js ├── this-in-ES6_2.js └── this-in-ES6_3.js ├── Functional-Programming ├── 1.js ├── max.js └── pure_functions.js ├── General-JS-Problems ├── Pi-To-n-th-digits.js ├── asyncMap.js ├── atoi-string-to-Number-2.js ├── atoi-string-to-number.js ├── caching_memoization-function.js ├── calculate-log-recursively.js ├── check-nonEmptyString.js ├── comparing-number-to-string.txt ├── convert-integer-to-words-2.js ├── convert-integer-to-words.js ├── convert-word-to-integer-atoi.js ├── count-vowels.js ├── decimal-to-roman.js ├── factorial-Performance-Recursive-vs-Iterative.js ├── fibonacci-number-GOOD-Future-Ref.js ├── fibonacci-number.js ├── fibonacci-sum-odd.js ├── fibonacci-with-memoization.js ├── find_number_appearing-twice.js ├── form-largest-number-from-given-array.js ├── function_chaining-call-function-inside-another-as-object-property.js ├── greatest_common_divisor.js ├── ifPowerOfFour.js ├── integer_length.js ├── intersection-of-arrays.js ├── isNumeric.js ├── isPalindrome.js ├── isUgly.js ├── largest-Numbe-in-Array.js ├── largest-second-value-from-Array-Multiple-Solution.js ├── largest-third-value-from-Array-Multiple-Solution.js ├── largest_product_yielded_ from_three_ integers.js ├── linked-list.js ├── map-and-filter-application.js ├── max-min-from-array-of-objects.js ├── max-product-three-elements.js ├── median-of-Array.js ├── merge_two_sorted_array.js ├── missing-number.js ├── multi-diamensional-array.js ├── narcissistic _number.js ├── nested-arrays-1.js ├── nested-arrays-function-chaining2.js ├── non-repeating-char-in-a-string.js ├── pangram.js ├── parenthesis-match.js ├── parenthesis_return-matching-ending.js ├── permutation_array_of_numbers-Heap-Algo.js ├── permutation_array_of_numbers-backtrack.js ├── permutation_array_of_text-string.js ├── pipeFunction.js ├── print-Triangle-Staircase-1.js ├── print-Triangle-Staircase-2.js ├── print-Triangle-Staircase-REVERSE-2.js ├── print-pyramid-Reverse.js ├── print-pyramid-structure.js ├── print-right-aligned-triangel-staircase-problem-HR.js ├── print-side-by-side-bow-shape-triangle.js ├── pure-impure-func-with-slice-and-splice.js ├── raise-To-Power-bit-shifting.js ├── random-code-1.js ├── remove-duplicate-chars-from-string.js ├── remove-duplicate-from-Array-O(n).js ├── remove-duplicate-from-array.js ├── remove-duplicate-from-string.js ├── repeatedly-add-digits-till-sum-is-single.js ├── reverseArray-of-numbers.js ├── search-string-heighlight.html ├── secretary-hiriing.js ├── setTimeOut-As-Callback.js ├── shuffle-array-so-all-zeros-are-at-beginning.js ├── small-exercise.js ├── small-snippets.js ├── sort-array-of-objects.js ├── sum-integers-without-Operator.js ├── sum-large-numbers.js └── swapNumber-without-temp.js ├── Imp-TECHNIQUES ├── convert-String-Arr-to-IntArray.js ├── do-While-loop-Guessing-Game.js ├── general-Array-Creation.js ├── generate-2-D-array-on-the-fly-inside-a-program.js ├── generate-array-on-the-fly.js ├── method_chaining.js ├── parse-Int-toString.js ├── replace-splice-with-slice.js └── spread-operator-for-multiple-arguments.js ├── Most-Popular ├── Numbers │ └── swapNumber-without-temp.js ├── Prime-Num │ ├── find_Prime_factors.js │ ├── isPrime.js │ ├── prime-Find-nth-Prime-Number.js │ ├── prime-generation-between-Range.js │ ├── prime-num-between-range-Eratosthenes-algorithm.js │ ├── prime-num-between-range.js │ └── prime_palindrome.js ├── String │ ├── reverse-string-multiple-ways.js │ ├── reverseArray-of-numbers.js │ └── reverseWords.js ├── anagram.js ├── count-vowels.js ├── counting-zeros-in-number.js └── quick-sort-with-Counter.js ├── Objects-Master-List-of-Problems-Super-Useful-Daily-Techniques ├── Delete-Prop-with-numbers-as-keys-regulal-destructuring-wont-work.js ├── Lodash_Usefull_Techniques │ └── pick-partialRight_Only_cherryPick_Objects.js ├── Object-of-arrays-with-further-nested-array-return-an-element-meeting-condition.js ├── Object.assign.md ├── array-map-like-function-for-Objects.js ├── array-of-objects-1.js ├── cloninng_Shallow-with-assign-method.js ├── cloninng_deep-2.js ├── cloninng_deep.js ├── convert-2D-Obj-to-arr-of-Obj-Highcharts-multiple-bar-graph.js ├── convert-arr-of-obj-to-arr-of-arr-removing-some-fields-useful-external-api.js ├── convert-arr-of-objects-into-another-dynamically-add-field-useful-for-api-request.js ├── convert-obj-of-key-value-pairs-to-arrays-DeNormalization.js ├── convert-obj-of-nested-obj-to-arr-of-arr-worldtrading-data-api-with-vx-chart.js ├── convert-plain-object-to-array-of-objects-useful-external-api.js ├── copy-one-object-to-another-object.js ├── delete_Properties_with_rest_spread.js ├── flatten-2d-arrays-picking-only-second-element-highcharts.js ├── flatten-objects-plain-js-recursive.js ├── getting-key-with-max-value-from-object.js ├── json-accessing-json-objects.js ├── lodash-pick-object-fields-from-array.js ├── map-Implementation-On-Objects.js ├── map-over-arr-of-objects-to-return-value-conditionally-as-an-ar.js ├── map-recduce-filter.js ├── max-min-from-array-of-objects.js ├── merge-objects-with-spread-operator.js ├── nested-object-prob-1.js ├── nested-objects-4.js ├── nested-objects-prob-2.js ├── nested-objects-prob-3.js ├── number-as-key-in-obj-is-it-allowed.md ├── object-accessing-keys-values.js ├── object-seal-and-freeze.js ├── object-with-nested-arrays-values.js ├── property-descriptor.md ├── push-nested-array-of-objects-to-another-2.js ├── push-nested-array-of-objects-to-another.js ├── pushing_new_key_value_pair_to_existing_obj.js └── sort-array-of-objects.js ├── Promise-Notes ├── How-Promise-makes-code-Asynchronous-non-blocking.md ├── README.md ├── calback-hell-resolved-with-promise.js ├── callback-hell-examples.js ├── promise-basic-implementation.js └── then-in-Promise-Future-Reference-GOOD.md ├── Readme.md ├── Regexp ├── check-if-String-has-NO-numbers.js ├── check-if-String-has-only-numbers.js ├── match-basics.js ├── pigLatin-with-match.js ├── regExp-Method-Impotant-for-String.js ├── replace-method-basics.js ├── search-method-basics.js └── test-method-basics.js ├── String ├── camel-to-Title.js ├── frequency-of-occurance-of-letters.js ├── longest_Substring-of-two-strings.js ├── no-of-occurance-of-char-in-string.js ├── padded-Number.js ├── passage-Counter.js ├── reverse-string-multiple-ways.js ├── shift-each-letter-by-number.-of-position.js ├── string-related-misc-problems.js ├── string-splice-method.js ├── title-To-Camel.js ├── toLocalString-Application.js └── tweet-word-limits.js ├── careercup └── google-biz-trip-boardingPass.js ├── date-conversion-comparison-moment ├── convert-string-date-from-MUI-pickert-to-YYYY-MM-DD.js └── mongo-Date-Comparison-with-current-date.js ├── numbers └── summing-digits-of-a-number-subtracting-first-digit-if-negative.js ├── package-lock.json ├── package.json ├── reWrite-JS-Function ├── every-myOwn-custom-callback.js ├── filter-myOwn-custom-callback.js ├── forEach-myOwn-custom-callback.js ├── indexOf-myOwn-custom-callback.js ├── map-myOwn-custom-callback.js ├── reduce-myOwn-custom-callback.js └── some-myOwn-custom-callback.js ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | 23 | # Ignore docs files 24 | _gh_pages 25 | .ruby-version 26 | 27 | # Numerous always-ignore extensions 28 | *.diff 29 | *.err 30 | *.orig 31 | *.log 32 | *.rej 33 | *.swo 34 | *.swp 35 | *.zip 36 | *.vi 37 | *~ 38 | *.~lock* 39 | .~lock* 40 | 41 | # OS or Editor folders 42 | .DS_Store 43 | ._* 44 | Thumbs.db 45 | .cache 46 | .project 47 | .settings 48 | .tmproj 49 | *.esproj 50 | nbproject 51 | *.sublime-project 52 | *.sublime-workspace 53 | .idea 54 | 55 | # Komodo 56 | *.komodoproject 57 | .komodotools 58 | 59 | # grunt-html-validation 60 | validation-status.json 61 | validation-report.json 62 | 63 | # Folders to ignore 64 | node_modules 65 | Project-Note-PAUL 66 | .vscode 67 | 68 | # Ignore all logfiles and tempfiles. 69 | !/log/.keep 70 | /tmp 71 | /.gems 72 | 73 | CountDownTimer-Note.odt 74 | random-code-1.js 75 | random-code-2.js 76 | random-code-3.js 77 | performance-1.js 78 | 79 | #ignore file name ending in "-bkp.js" OR "-bkp.ts" OR "-bkp.py" or "-test.js" OR "-test.ts" in its name. So I will have to put "-test.js" at all files that is just for my development-time random testing code . 80 | **/*-bkp.js 81 | **/*-bkp.ts 82 | **/*-bkp.py 83 | **/*-test.js 84 | **/*-test.ts 85 | **/*-test.py 86 | **/*-test.ipynb 87 | **/*-test.md 88 | **/*-test.json 89 | -------------------------------------------------------------------------------- /Array-Problems/array-complements.js: -------------------------------------------------------------------------------- 1 | // returns things in array 'a' that are not in array 'b' 2 | // ['a','b','c','1', '2', '3'].complement(['b', 'c', 'd', 'e']); 3 | // ['a', '1', '2', '3'] 4 | 5 | complements = (arr1, arr2) => { 6 | 7 | return (Array.isArray(arr1) && Array.isArray(arr2)) 8 | ? arr1.filter((elem) => arr2.indexOf(elem) === - 1) 9 | : undefined 10 | } 11 | 12 | let arr1 = ['a','b','c','1', '2', '3']; 13 | let arr2 = ['b', 'c', 'd', 'e']; 14 | 15 | console.log(complements(arr1, arr2)); // => [ 'a', '1', '2', '3' ] -------------------------------------------------------------------------------- /Array-Problems/array-of-Objects-mutate-formatting-Mongo-date-Performance.js: -------------------------------------------------------------------------------- 1 | const { data } = require("./mongo-json-data-TEST"); 2 | const moment = require("moment"); 3 | 4 | /* Problem Statement - From call to Mongo, I am getting the date field formatted according to Mongo's own formatting syntax. But after getting the raw data from Mongo, I shall format each of the date field to whatever formatting I need 5 | 6 | The Performance test here, implements the problem from file - array-of-Objects-mutate-formatting-Mongo-date 7 | 8 | 9 | */ 10 | 11 | /* 12 | The basic idea is to create a new empty object for each item in the array and assign the properties from old objects to them, respectively. This means we get an object with a new reference, so we are not going to modify the Original One. 13 | */ 14 | const doNotMutateOriginalArr = (arr) => { 15 | let mutatedArr = arr.map(e => { 16 | if (e.imported_date) { 17 | e = { 18 | ...e, 19 | imported_date: 20 | moment(e.imported_date).format("MMM D, YYYY 12:00:00 ") + `AM` 21 | }; 22 | } 23 | return e; 24 | }); 25 | return mutatedArr 26 | } 27 | 28 | // In this function, I am mutating the original array itself. 29 | 30 | const mutateOriginalArr = (arr) => { 31 | arr.map(e => { 32 | if (e.imported_date) { 33 | e.date = moment(e.imported_date).format("MMM D, YYYY 12:00:00 ") + `AM` 34 | } 35 | return e; 36 | }) 37 | return arr; 38 | } 39 | 40 | // console.log(doNotMutateOriginalArr(data)); 41 | // console.log(mutateOriginalArr(data)); 42 | 43 | 44 | console.time("1st"); 45 | doNotMutateOriginalArr(data) 46 | console.timeEnd("1st"); 47 | 48 | console.log("*******************************"); 49 | 50 | console.time("2nd"); 51 | mutateOriginalArr(data) 52 | console.timeEnd("2nd"); -------------------------------------------------------------------------------- /Array-Problems/array-of-Objects-mutate-simple.js: -------------------------------------------------------------------------------- 1 | const events = [ 2 | { 3 | name: "First Event", 4 | metadata: { 5 | type: "public" 6 | } 7 | }, 8 | { 9 | name: "Event 2", 10 | metadata: { 11 | type: "private" 12 | } 13 | }, 14 | { 15 | name: "Third Event", 16 | metadata: { 17 | type: "closed" 18 | } 19 | } 20 | ]; 21 | 22 | /* FROM BLOG POST - https://medium.freecodecamp.org/handling-state-in-react-four-immutable-approaches-to-consider-d1f5c00249d5 23 | 24 | Note, here I am NOT mutating the original array. 25 | The basic idea is to create a new empty object for each item in the array and assign the properties from old objects to them, respectively. This means we get an object with a new reference, so we are not going to modify the Original One. 26 | */ 27 | const mappedEvents = events.map(e => { 28 | if (e.name) { 29 | e = { ...e, name: "Second Event Mutated" }; 30 | } 31 | return e; 32 | }); 33 | 34 | console.log(mappedEvents); 35 | 36 | /* OUTPUT - 37 | [ { name: 'Second Event Mutated', metadata: { type: 'public' } }, 38 | { name: 'Second Event Mutated', metadata: { type: 'private' } }, 39 | { name: 'Second Event Mutated', metadata: { type: 'closed' } } ] 40 | */ 41 | -------------------------------------------------------------------------------- /Array-Problems/array-right-rotation-by-no-of-positions.js: -------------------------------------------------------------------------------- 1 | /* Write a function that takes an array of integers and returns that array rotated by N positions. 2 | For example, if N=2, given the input array [1, 2, 3, 4, 5, 6] the function should return [5, 6, 1, 2, 3, 4] */ 3 | 4 | /* A> Rotating an array is the same as chopping it into two pieces and putting them together "backwards". 5 | 6 | B> So, for rotation, chop this array into 2 pieces the last 3 elements, and the rest of the elements. 7 | 8 | C> Now just bring those last 3 elements into first positon and concatenate the rest of the elements to this. 9 | */ 10 | 11 | function rightRotate (array, k) { 12 | var L = array.length; 13 | return array.slice(L - k).concat(array.slice(0, L - k)); 14 | }; 15 | 16 | console.log(rightRotate([1,2,3,4,5,6,7], 3)); -------------------------------------------------------------------------------- /Array-Problems/find-closest-number-in-array.js: -------------------------------------------------------------------------------- 1 | // Find the number in an array that is closest to a given number 2 | 3 | // sort based on distance from the reference value num, and then take the first item. 4 | closestNumInArr = (arr, num) => { 5 | return arr.sort((a, b) => Math.abs(num - a) - Math.abs(num - b))[0]; 6 | } 7 | 8 | console.log(closestNumInArr([5,10,15,20,25,30,35], 22)); -------------------------------------------------------------------------------- /Array-Problems/find-count-of-max-elements.js: -------------------------------------------------------------------------------- 1 | /* Source Problem - https://youtu.be/E_hTGcx8o7g?t=3m24s - The Indian guy doing mock interview 2 | 3 | Given an array containing multiple number of max elements - count the number of max elements. 4 | 5 | so, given [ 1, 2, 2, 3, 4, 5, 4, 5] 6 | 7 | I should return 2 as 5 occurs 2 times. 8 | */ 9 | 10 | maxCount = arr => { 11 | 12 | arr = arr.sort((a, b) => b - a); 13 | 14 | let max = Math.max(...arr); 15 | 16 | result = 0; 17 | 18 | for (let i = 0; i < arr.length; i++ ) { 19 | if (max === arr[i]) { 20 | result++ 21 | } 22 | if (arr[i] < max) break; 23 | } 24 | return result; 25 | } 26 | 27 | 28 | let myArr = [ 1, 2, 2, 3, 4, 5, 4, 5] 29 | 30 | console.log(maxCount(myArr)); -------------------------------------------------------------------------------- /Array-Problems/find-min-max-of-after-popping-one-elem.js: -------------------------------------------------------------------------------- 1 | // https://youtu.be/hbp6IrCysDs?t=3m3s - The Indian guy doing mock interview. given an array, write a function to return the maximum and minimum possible sum of all the rest of the elements, after taking out a random element from the array. 2 | 3 | // Solution Algo - After sorting the array, when I leave the max element (i.e. the right-most elem) the rest of the array sum will be he minimum sum. And similarly, when I leave the left-most elem, the sum of the rest of elements are the max sum. 4 | 5 | minMax_after_popping_one_Elem = arr => { 6 | 7 | // Remember slice() method does not include the second argument in the returned sliced array. So it takes elements upto but not including the second-argumet. 8 | // And the js-native sort method will sort in ascending order with the largest element at the right-most position. 9 | 10 | let minSum = arr.sort().slice(0, arr.length - 1).reduce((a, b) => a + b); 11 | 12 | let maxSum = arr.sort().slice(1, arr.length).reduce((a, b) => a + b); 13 | 14 | return console.log(minSum, maxSum); 15 | 16 | } 17 | 18 | myArr = [ 2, 1, 3, 4] 19 | 20 | minMax_after_popping_one_Elem(myArr); 21 | 22 | // Slight modification with destructuring assignment 23 | 24 | minMax = arr => [min, max] = [(arr.sort().slice(0, arr.length - 1)).reduce((a, b) => a + b), (arr.sort().slice(1, arr.length)).reduce((a, b) => a + b) ] 25 | 26 | console.log(minMax(myArr)); -------------------------------------------------------------------------------- /Array-Problems/flatten-Array-Deep-2.js: -------------------------------------------------------------------------------- 1 | // Recursive helper function 2 | const flattenArr_TerminalCondition = ([first, ...rest], accumulator) => 3 | (first === undefined ) 4 | ? accumulator 5 | : (Array.isArray(first)) 6 | ? flattenArr_TerminalCondition([...first, ...rest], accumulator) 7 | : flattenArr_TerminalCondition(rest, accumulator.concat(first)); 8 | 9 | 10 | const flattenDeep = array => flattenArr_TerminalCondition(array, []); 11 | 12 | console.log(flattenDeep([[1,[2,[[3]]]],4,[5,[[[6]]]]])) -------------------------------------------------------------------------------- /Array-Problems/flatten-arr-of-objects-with-flat-package.js: -------------------------------------------------------------------------------- 1 | /* Problem Statement - All I am trying to do is to create a new array with a an extra field name of "imported_commodity_name" (from the nested object) from original array (receieved from DB -call) which does not have that extra field 2 | */ 3 | 4 | var flatten = require("flat"); 5 | 6 | var data = [ 7 | { 8 | _id: "5c76bc3a5ff10c6d53ef67b4", 9 | imported_commodity_objectId: { 10 | _id: "5c651f71ddff9f780e4cdbcd", 11 | name: "Platinum12", 12 | type: "Precious Metals", 13 | createdAt: "2019-02-14T07:57:37.736Z", 14 | updatedAt: "2019-02-27T16:35:22.214Z", 15 | __v: 0 16 | }, 17 | qty_in_mts: 1, 18 | imported_date: "2019-02-27T16:34:18.281Z", 19 | no_of_vessels_per_day: 1, 20 | createdAt: "2019-02-27T16:35:06.071Z", 21 | updatedAt: "2019-02-27T16:35:06.071Z", 22 | __v: 0 23 | }, 24 | { 25 | _id: "5c76bc305ff10c6d53ef67b3", 26 | imported_commodity_objectId: { 27 | _id: "5c6c0f6e9c84ea3c7194a7dc", 28 | name: "Oil", 29 | type: "Energy", 30 | createdAt: "2019-02-19T14:15:10.421Z", 31 | updatedAt: "2019-02-19T14:15:10.421Z", 32 | __v: 0 33 | }, 34 | qty_in_mts: 1, 35 | imported_date: "2019-02-27T16:34:18.281Z", 36 | no_of_vessels_per_day: 1, 37 | createdAt: "2019-02-27T16:34:56.790Z", 38 | updatedAt: "2019-02-27T16:34:56.790Z", 39 | __v: 0 40 | } 41 | ]; 42 | 43 | const list = flatten(data, { safe: true }); 44 | 45 | console.log(list); 46 | -------------------------------------------------------------------------------- /Array-Problems/flatten-arr-of-objects-with-lodash-flatMap-2.js: -------------------------------------------------------------------------------- 1 | /* 2 | https://stackoverflow.com/questions/47165218/lodash-flatmap-to-flatten-object?rq=1 3 | 4 | GREAT SOLUTION BASED ON WHICH I CREATED MY OWN MORE SIMPLIFIED SOLUTION (flatten-arr-of-objects-with-lodash-flatMap.js) TO GET A PARTICULAR NESTED OBJECT'S VALUE 5 | 6 | I am trying to pull out all of the start and end times from allocationIntervals.jobTaskTimeAllocationInterval to create something like the following: 7 | 8 | const arr = [{ 9 | employeeId: "22826", 10 | taskId: "16465169" 11 | startTime: "2017-03-15T01:50:00.000Z", 12 | endTime: "2017-03-15T02:50:00.000Z" 13 | }, 14 | { 15 | employeeId: "22826", 16 | taskId: "16465169", 17 | startTime: "2017-04-16T02:50:00.000Z", 18 | endTime: "2017-04-16T03:50:00.000Z" 19 | }]; 20 | 21 | */ 22 | 23 | const _ = require("lodash"); 24 | const flatMap = require("lodash/flatMap"); 25 | 26 | const arr = [ 27 | { 28 | "@id": "6005752", 29 | employeeId: { 30 | id: "22826" 31 | }, 32 | allocationIntervals: { 33 | jobTaskTimeAllocationInterval: { 34 | "@id": "34430743", 35 | startTime: "2017-03-15T01:50:00.000Z", 36 | endTime: "2017-03-15T02:50:00.000Z" 37 | }, 38 | "@id": "34430756", 39 | startTime: "2017-04-16T02:50:00.000Z", 40 | endTime: "2017-04-16T03:50:00.000Z" 41 | }, 42 | taskId: { 43 | id: "16465169" 44 | } 45 | } 46 | ]; 47 | 48 | const createAllocation = (item, allocation) => ({ 49 | employeeId: item.employeeId.id, 50 | taskId: item.taskId.id, 51 | startTime: allocation.startTime, 52 | endTime: allocation.endTime 53 | }); 54 | 55 | const result = _.flatMap(arr, item => [ 56 | createAllocation(item, item.allocationIntervals), 57 | createAllocation(item, item.allocationIntervals.jobTaskTimeAllocationInterval) 58 | ]); 59 | 60 | console.log(result); 61 | -------------------------------------------------------------------------------- /Array-Problems/flatten-arr-of-objects-with-lodash-merge.js: -------------------------------------------------------------------------------- 1 | /* Problem Statement - All I am trying to do is to create a new array with a an extra field name of "imported_commodity_name" (from the nested object) from original array (receieved from DB -call) which does not have that extra field 2 | 3 | PAUL NOTE - merge will work ONLY FOR OBJECTS 4 | */ 5 | 6 | const _ = require("lodash"); 7 | const merge = require("lodash/merge"); 8 | 9 | var data = [ 10 | { 11 | _id: "5c76bc3a5ff10c6d53ef67b4", 12 | imported_commodity_objectId: { 13 | _id: "5c651f71ddff9f780e4cdbcd", 14 | name: "Platinum12", 15 | type: "Precious Metals", 16 | createdAt: "2019-02-14T07:57:37.736Z", 17 | updatedAt: "2019-02-27T16:35:22.214Z", 18 | __v: 0 19 | }, 20 | qty_in_mts: 1, 21 | imported_date: "2019-02-27T16:34:18.281Z", 22 | no_of_vessels_per_day: 1, 23 | createdAt: "2019-02-27T16:35:06.071Z", 24 | updatedAt: "2019-02-27T16:35:06.071Z", 25 | __v: 0 26 | }, 27 | { 28 | _id: "5c76bc305ff10c6d53ef67b3", 29 | imported_commodity_objectId: { 30 | _id: "5c6c0f6e9c84ea3c7194a7dc", 31 | name: "Oil", 32 | type: "Energy", 33 | createdAt: "2019-02-19T14:15:10.421Z", 34 | updatedAt: "2019-02-19T14:15:10.421Z", 35 | __v: 0 36 | }, 37 | qty_in_mts: 1, 38 | imported_date: "2019-02-27T16:34:18.281Z", 39 | no_of_vessels_per_day: 1, 40 | createdAt: "2019-02-27T16:34:56.790Z", 41 | updatedAt: "2019-02-27T16:34:56.790Z", 42 | __v: 0 43 | } 44 | ]; 45 | 46 | const list = _.merge(data, data.imported_commodity_objectId); 47 | 48 | console.log(list); 49 | -------------------------------------------------------------------------------- /Array-Problems/flatten_array.js: -------------------------------------------------------------------------------- 1 | // SMALLEST SIMPLEST Functional solution for flattening 2-D arrays - Works for 2-D arrays but DOES NOT FOR more multi-dimensional arrays 2 | 3 | const flattened1 = arr => [].concat(...arr) 4 | 5 | let myArr1 = [[1], [2], [3, 4], 5] 6 | let myArr2 = [[1], [2], [[3], 4], 5] 7 | var myArr3 = [ 8 | [1, 2], 9 | [3, 4, 5], 10 | [6, 7, 8, 9], 11 | ] 12 | 13 | console.log(flattened1(myArr1)) // => [ 1, 2, 3, 4, 5 ] 14 | console.log(flattened1(myArr2)) // => [ 1, 2, [ 3 ], 4, 5 ] 15 | console.log(flattened1(myArr3)) // => [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] 16 | 17 | // ******************************************************************* 18 | 19 | // Other alternative 20 | 21 | var arrays = [["a"], ["b", "c"]] 22 | 23 | console.log(Array.prototype.concat.apply([], arrays)) // => [ 'a', 'b', 'c' ] 24 | 25 | // Good old O(N^2) solution for 2-D arrays - BUT IF ANY OF THE ELEMENT IS NO AN ARRAY, THEN IT WILL FAIL, AS IT WILL NOT INCLUDE A NON-ARRAY ELEMENT INTO THE FINAL ARRAY 26 | 27 | const flatten_2d = arr => { 28 | let flattenedArr = [] 29 | 30 | for (let i = 0; i < arr.length; i++) { 31 | for (let j = 0; j < arr[i].length; j++) { 32 | flattenedArr.push(arr[i][j]) 33 | } 34 | } 35 | return flattenedArr 36 | } 37 | 38 | console.log(flatten_2d(myArr1)) // => [ 1, 2, 3, 4 ] 39 | console.log(flatten_2d(myArr2)) // => [ 1, 2, [ 3 ], 4 ] 40 | console.log(flatten_2d(myArr3)) // => [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] 41 | -------------------------------------------------------------------------------- /Array-Problems/flatten_array_Deep.js: -------------------------------------------------------------------------------- 1 | /* SOLUTION-1 - BEST IMPLEMENTATION FOR Deep flattening a multi-diamensional array. 2 | 3 | Use recursion. Use Array.concat() with an empty array ([]) and the spread operator (...) to flatten an array. Recursively flatten each element that is an array.*/ 4 | 5 | const deepFlatten1 = arr => [].concat(...arr.map(toFlatten => { 6 | 7 | return (Array.isArray(toFlatten) ? deepFlatten1(toFlatten) : toFlatten) 8 | 9 | })) 10 | 11 | console.log(deepFlatten1([1, [2], [[3], 4], 5])); // => [ 1, 2, 3, 4, 5 ] 12 | 13 | // SOLUTION-2 - Same implementation using reduce() and without using arrow syntax 14 | 15 | const deepFlatten2 = arr => { 16 | return arr.reduce((flat, yetToFlatten) => { 17 | return flat.concat(Array.isArray(yetToFlatten) ? deepFlatten2(yetToFlatten) : yetToFlatten); 18 | }, []); 19 | } 20 | 21 | let myArr1 = [[1], [2], [3, 4], 5] 22 | 23 | console.log(deepFlatten2(myArr1)); // => [ 1, 2, 3, 4, 5 ] 24 | 25 | /*My Note - Explanation of why an empty array passed as the second argument to the reduce function which is the accumulator - The code breaks without it, giving arr.reduce is not a function. 26 | 27 | The empty array [] is the starting accumulator value for the reduce function, the initial value. In this case it's the value of flat in the first call to the anonymous function passed to reduce. If it is not specified, then the first call to reduce binds the first element out of the array-argument given to deepFlatten2() function to flat, which in the above test-case would result in 1 (the first element of the argument) being bound to flat in both the examples. 1.concat is not a function 28 | 29 | */ 30 | 31 | // SOLUTION-3 - huge (e.g. 200 000 elements) arrays and also works on nested arrays 32 | 33 | const flattenLargeArray = function(arr, result = []) { 34 | 35 | for (let i = 0, length = arr.length; i < length; i++) { 36 | 37 | const value = arr[i]; 38 | 39 | if (Array.isArray(value)) { 40 | 41 | flattenLargeArray(value, result); 42 | } else { 43 | result.push(value); 44 | } 45 | } 46 | return result; 47 | }; 48 | 49 | 50 | console.log(flattenLargeArray([1, [1], [[3]]])); 51 | 52 | console.log(flattenLargeArray(Array(2).fill(Array(2).fill(Array(2).fill([1]))))); 53 | 54 | console.log(flattenLargeArray([[1],[2,3],[4]])); 55 | 56 | console.log(flattenLargeArray([1, [2], [[3], 4], 5])); 57 | -------------------------------------------------------------------------------- /Array-Problems/forEach-first-Principle-custom-callback.js: -------------------------------------------------------------------------------- 1 | // filter - Implement your owen Array.prototype.map function 2 | // Solution - 1 3 | 4 | Array.prototype.myMap = function (callback) { 5 | 6 | arr = [] 7 | 8 | for (let i = 0; i < this.length; i++) { 9 | 10 | arr.push(callback(this[i], i, this)); 11 | } 12 | return arr; 13 | } 14 | 15 | let numbers = [ 1, 4, 9 ] ; 16 | 17 | let squareRoot = numbers.myMap(i => Math.sqrt(i)) 18 | 19 | console.log(squareRoot); // => [ 1, 2, 3 ] 20 | 21 | 22 | // Without using Array.prototype 23 | 24 | myMap2 = (array, callback) => { 25 | 26 | let arr = []; 27 | 28 | for (let i = 0; i < array.length; i++) { 29 | arr.push(callback(array[i], i, this)) 30 | } 31 | return arr; 32 | } 33 | 34 | let squareRoot1 = myMap2(numbers, (num) => { 35 | return Math.sqrt(num) 36 | }) 37 | 38 | console.log(squareRoot1); // => [ 1, 2, 3 ] -------------------------------------------------------------------------------- /Array-Problems/indexOf_manually_build.js: -------------------------------------------------------------------------------- 1 | /* Problem Statement - 2 | Build the function indexOf, for the case when the browser does not support the function natively. 3 | */ 4 | 5 | if(!Array.prototype.indexOf) { 6 | Array.prototype.indexOf = function indexOf(searchElement, startFromIndex) { 7 | if(startFromIndex == null) { 8 | startFromIndex = 0; 9 | } else if (startFromIndex < 0) { 10 | startFromIndex = Math.max(0, (this.length + startFromIndex)); 11 | } 12 | for (var i = startFromIndex; i < this.length; i++ ) { 13 | if (this[i] === searchElement) 14 | return i; 15 | } 16 | return -1; 17 | }; 18 | } 19 | 20 | /*My Own learning note - Note that when variable startFromIndex < 0, we are updating its value by adding it with length of the array - based on the official definition of this argument when its negative - "it is taken as the offset from the end of the array". And "the array is still searched from front to back" So if startFromIndex is passed a value of -1 and the array has a length of 3, the indexOf function will start its searching from index position of 1 towards right. 21 | */ -------------------------------------------------------------------------------- /Array-Problems/largest-numbers-from-subarray.js: -------------------------------------------------------------------------------- 1 | /* https://www.freecodecamp.org/challenges/return-largest-numbers-in-arrays 2 | 3 | Return an array consisting of the largest number from each provided sub-array. For simplicity, the provided array will contain exactly 4 sub-arrays. So the given sub-array will be a 2D Array of Arrays 4 | 5 | largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]]) should return [27,5,39,1001] */ 6 | 7 | function largestOfFour(arr) { 8 | 9 | let maxArray = [0, 0, 0, 0]; 10 | 11 | for (let outerIndex = 0; outerIndex < arr.length; outerIndex++) { 12 | for (let innerIndex = 0; innerIndex < arr[outerIndex].length; innerIndex++) { 13 | if (arr[outerIndex][innerIndex] > maxArray[outerIndex]) { 14 | maxArray[outerIndex] = arr[outerIndex][innerIndex] ; 15 | } 16 | } 17 | } 18 | return maxArray; 19 | } 20 | 21 | console.log(largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]])); -------------------------------------------------------------------------------- /Array-Problems/map-first-Principle-custom-callback.js: -------------------------------------------------------------------------------- 1 | // filter - Implement your owen Array.prototype.map function 2 | // Solution - 1 3 | 4 | Array.prototype.myMap = function (callback) { 5 | 6 | arr = [] 7 | 8 | for (let i = 0; i < this.length; i++) { 9 | 10 | arr.push(callback(this[i], i, this)); 11 | } 12 | return arr; 13 | } 14 | 15 | let numbers = [ 1, 4, 9 ] ; 16 | 17 | let squareRoot = numbers.myMap(i => Math.sqrt(i)) 18 | 19 | console.log(squareRoot); // => [ 1, 2, 3 ] 20 | 21 | 22 | // Without using Array.prototype 23 | 24 | myMap2 = (array, callback) => { 25 | 26 | let arr = []; 27 | 28 | for (let i = 0; i < array.length; i++) { 29 | arr.push(callback(array[i], i, this)) 30 | } 31 | return arr; 32 | } 33 | 34 | let squareRoot1 = myMap2(numbers, (num) => { 35 | return Math.sqrt(num) 36 | }) 37 | 38 | console.log(squareRoot1); // => [ 1, 2, 3 ] -------------------------------------------------------------------------------- /Array-Problems/max-repeated-num-in-array.js: -------------------------------------------------------------------------------- 1 | // given an array of integers, find the number that is repeated the most. 2 | 3 | maxRepeatNum = arr => { 4 | 5 | let elemHash = {}; 6 | 7 | for (let i of arr) { 8 | if (elemHash[i]) { 9 | elemHash[i] += 1 10 | } else { 11 | elemHash[i] = 1 12 | } 13 | } 14 | // return elemHash // => { '1': 2, '2': 1, '3': 2, '5': 3, '8': 1 } // this is just for debugging 15 | 16 | // Now return the the key that has the max value, I have few option for that 17 | 18 | // Option-1 - Getting key with the highest value from object 19 | // return Object.keys(elemHash).reduce((a, b) => (elemHash[a] > elemHash[b]) ? a : b ) // => 5 20 | 21 | 22 | //Option-2 - Getting key with the highest value from object 23 | let max = Math.max(...(Object.keys(elemHash).map(i => elemHash[i]))) 24 | // so max is now the highest value that I have in the entire object 25 | // So, now I have to find the key given this highest value 26 | return Object.keys(elemHash).filter(i => elemHash[i] === max)[0]; // => 5 27 | 28 | } 29 | 30 | let myArr = [ 1, 2, 1, 3, 5, 5, 8, 3, 5] 31 | 32 | console.log(maxRepeatNum(myArr)); // => 5 33 | 34 | -------------------------------------------------------------------------------- /Array-Problems/max-repeating-element.js: -------------------------------------------------------------------------------- 1 | /* Get the element with the highest occurrence in an array 2 | 3 | https://www.geeksforgeeks.org/find-the-maximum-repeating-number-in-ok-time/ 4 | 5 | The naive approach is to run two loops, the outer loop picks an element one by one, the inner loop counts number of occurrences of the picked element. Finally return the element with maximum count. Time complexity of this approach is O(n^2). 6 | 7 | A better approach is to create a count array of size k and initialize all elements of count[] as 0. Iterate through all elements of input array, and for every element arr[i], increment count[arr[i]]. Finally, iterate through count[] and return the index with maximum value. This approach takes O(n) time, but requires O(k) space. 8 | 9 | For example, in ['pear', 'apple', 'orange', 'apple'] the 'apple' element is the most frequent one. 10 | 11 | */ 12 | 13 | maxRepeatingElem = arr => { 14 | 15 | var counter = {}; 16 | 17 | for (let i of arr) { 18 | 19 | (counter[i] == null ) ? ( counter[i] = 1 ) : counter[i]++ 20 | 21 | } 22 | 23 | // Find the key given the max value from a key-value pair of object 24 | return Object.keys(counter).reduce((a, b) => counter[a] > counter[b] ? a : b) 25 | 26 | // Alternative to find the key given the max value from a key-value pair of object - i.e. I could replace the above return with the below 27 | // return Object.keys(counter).find(i => counter[i] === Math.max(...Object.values(counter))); 28 | } 29 | 30 | 31 | let myArr = ['pear', 'apple', 'orange', 'apple']; 32 | 33 | console.log(maxRepeatingElem(myArr)); -------------------------------------------------------------------------------- /Array-Problems/misc_Array_Problems_JS-Cookbook.js: -------------------------------------------------------------------------------- 1 | /* Problem statement 1 - You want to convert an array of decimal numbers into a new array with their hexadecimal equivalents. 2 | */ 3 | 4 | var decimalArray = [23, 255, 122, 5, 16, 99]; 5 | 6 | var hexadecimalArray = decimalArray.map(function(element) { 7 | return element.toString(16); 8 | }); 9 | 10 | console.log(hexadecimalArray); 11 | 12 | 13 | /* Problem statement 2 - You want to filter element values in an array and assign the results to a new array. */ 14 | 15 | var charSet = ["**","bb","cd","**","cc","**","dd","**"]; 16 | 17 | var newArray = charSet.filter(function(element) { 18 | return (element !== "**"); 19 | }); 20 | 21 | console.log(newArray); 22 | 23 | /* Problem Statement 3 - You want to ensure that array contents meet certain criteria. In this case, ensure that every element in the array consists of alphabetical characters */ 24 | 25 | function testValue(element, index, array) { 26 | var testExp = /^[a-zA-Z]+$/; 27 | return testExp.test(element); 28 | }; 29 | 30 | var elementSet = ["**",123,"aaa","abc","-",46,"AAA"]; 31 | 32 | var result = elementSet.every(testValue); 33 | 34 | console.log(result); 35 | 36 | var elementSet2 = ["elephant","lion","cat","dog"]; 37 | 38 | var result2 = elementSet2.every(testValue); 39 | 40 | console.log(result2); 41 | 42 | /* The Array-problems some() method checks to ensure that at least some of the array elements are alphabetical strings*/ 43 | 44 | var result3 = elementSet.some(testValue); 45 | 46 | console.log(result3); 47 | 48 | /* Problem Statement 3 - */ -------------------------------------------------------------------------------- /Array-Problems/reduce_method_applications.js: -------------------------------------------------------------------------------- 1 | /* Problem Statement - 2 | Parse the array and return an object that contains the number of times each string occured in the array*/ 3 | 4 | var array = ["apple","orange","apple","orange","pear","orange"]; 5 | 6 | function getWordCount() { 7 | var previous = {}; 8 | return array.reduce(function(previous, next) { 9 | previous[next] = (previous[next] + 1) || 1; 10 | return previous; 11 | }, previous); 12 | } 13 | 14 | console.log(getWordCount()); 15 | 16 | /* 17 | My own learnin note - See another example of this kind of mechanism of grabbing the output into a nice object within curly braces, with property-value pairs, after doing some execution on the original array elements in Elequent Javascript book, page-92*/ 18 | -------------------------------------------------------------------------------- /Array-Problems/reverseArray-Recursively.js: -------------------------------------------------------------------------------- 1 | /* Problem Statement - 2 | Implement a function that will recursively traverse an array and return a string of the array element values, in reverse order*/ 3 | 4 | function reverseArray(arr, indx, str) { 5 | return indx == 0 ? str : reverseArray(arr, --indx, (str+= " " + arr[indx])); 6 | } 7 | 8 | /* Learning note on the above function - We start with the end of the array (as the requirement is to reverse the array elements), and with each iteration, we decrement indx AND ALSO update the 'str' parameter by adding the string value of that particular arr[index]. So on the very first iteration will yield 'motorbike'. 9 | */ 10 | 11 | var arr1 = ['car', 'boat', 'bike', 'motorbike']; 12 | console.log(reverseArray(arr1, arr1.length, "")); 13 | 14 | // Alternative to reverse an array with the 'z' pattern matching library 15 | 16 | require('z'); 17 | 18 | var myReverse = list => { 19 | return list.matches ( 20 | () => [], //match empty list (to check list ending) 21 | (head, tail) => myReverse(tail).concat(head) //match list head/tail to create reversed list recusively 22 | ) 23 | } 24 | console.log(myReverse(['car', 'boat', 'bike', 'motorbike'])); 25 | -------------------------------------------------------------------------------- /Array-Problems/search-unknown-length-Array.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | 3 | /* PROBLEM - Search Unknown Length Array - Given a sorted array of unknown length and a number to search for, return the index of the number in the array. Accessing an element out of bounds throws exception. If the number occurs multiple times, return the index of any occurrence. If it isn’t present, return -1. */ 4 | 5 | let myArr = [3, 5, 6, 7, 8]; 6 | 7 | console.log(myArr.indexOf(11)); -------------------------------------------------------------------------------- /Array-Problems/shuffle_Array-2.js: -------------------------------------------------------------------------------- 1 | // Slight variation of the BEST AND SIMPLE IN-PLACE SOLUTION IN O(n) time in the other file 2 | // Implementation of the Durstenfeld shuffle, a computer-optimized version of Fisher-Yates of the same Array shuffle problem 3 | 4 | shuffleArray = arr => { 5 | for (let i = arr.length - 1; i >= 0; i--) { 6 | let randIndex = Math.floor(Math.random() * ( i + 1)); 7 | [ arr[i], arr[randIndex] ] = [ arr[randIndex], arr[i] ] 8 | } 9 | return arr; 10 | } 11 | 12 | let myArr1 = [1, 2, 3, 4, 5] 13 | console.log(shuffleArray(myArr1)) 14 | 15 | // The running time of this algorithm is O(n). Note that the shuffle is done in-place. So if you do not want to modify the original array, make a copy of it first with .slice(0). -------------------------------------------------------------------------------- /Array-Problems/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | 2 | console.time("1st"); 3 | // _.flatMap(data, item => [createAllocation1(item)]); 4 | console.log(_.flatMap(data, item => [createAllocation1(item)])); 5 | console.timeEnd("1st"); 6 | 7 | console.log("*******************************"); 8 | 9 | console.time("2nd"); 10 | _.flatMap(data, item => [createAllocation2(item)]); 11 | console.timeEnd("2nd"); 12 | 13 | console.log("*******************************"); -------------------------------------------------------------------------------- /Array-Problems/tiny-Array-probs/clone_Array.js: -------------------------------------------------------------------------------- 1 | // Method-1 2 | let originalArray = [ 1, 2, 3] 3 | let [...arrayClone] = originalArray; 4 | console.log(arrayClone) // => [ 1, 2, 3 ] 5 | 6 | // Method-2 7 | let originalArray1 = [ 1, 2, 3] 8 | let arr2 = originalArray1.concat() 9 | console.log(arr2) // => [ 1, 2, 3 ] 10 | 11 | 12 | 13 | // Method-3 - Technically slice IS the fastest way, HOWEVER it is even faster if you add the 0 begin index. 14 | // myArray.slice(0) is faster than myArray.slice(); 15 | 16 | let originalArray2 = [ 1, 2, 3] 17 | let arr3 = originalArray1.slice(0) 18 | console.log(arr3) // => [ 1, 2, 3 ] 19 | 20 | // Method-4 21 | let originalArray3 = [ 1, 2, 3] 22 | let arr4 = originalArray1.splice(0) 23 | console.log(arr4) // => [ 1, 2, 3 ] 24 | 25 | /* Method-5 - Easiest way to deep clone Array or Object: 26 | this also inherits its limitations. Among other things, that means your array cannot contain undefined or any functions. Both of those will be converted to null for you during the JSON.stringify process. Other strategies, such as (['cool','array']).slice() will not change them but also do not deep clone objects within the array. So there is a tradeoff. 27 | Very bad perf and don't work with special objects like DOM, date, regexp, function 28 | 29 | The JSON.parse() method parses a JSON string, constructing the JavaScript value or object described by the string. 30 | The JSON.stringify() method converts a JavaScript value to a JSON string 31 | 32 | */ 33 | let originalArray4 = [ 1, 2, 3] 34 | let arr5 = JSON.parse(JSON.stringify(originalArray4)) 35 | console.log(arr5) // => [ 1, 2, 3 ] -------------------------------------------------------------------------------- /Array-Problems/tiny-Array-probs/returns-true-if-all-elemensts-true.js: -------------------------------------------------------------------------------- 1 | /*PROBLEM - 1 >> Returns true if the provided predicate function returns true for all elements in a collection, false otherwise. 2 | 3 | Use Array.every() to test if all elements in the collection return true based on fn. Omit the second argument, fn, to use Boolean as a default. */ 4 | 5 | all = (arr, fn = Boolean) => arr.every(fn); 6 | 7 | // console.log(all([4, 2, 3], x => x > 1)); 8 | 9 | // console.log(([4, 2, 3].every( x => x < 3 ))); 10 | 11 | 12 | /* PROBLEM - 2 >> Returns true if the provided predicate function returns true for at least one element in a collection, false otherwise. 13 | 14 | Use Array.some() to test if any elements in the collection return true based on fn. Omit the second argument, fn, to use Boolean as a default. */ 15 | 16 | any = (arr, fn = Boolean) => arr.some(fn); 17 | 18 | // console.log(any([4, 2, 3], x => x < 4)); 19 | 20 | console.log([4, 2, 3].some(x => x < 3)); 21 | 22 | -------------------------------------------------------------------------------- /ES6/Destructuring_Geneal.md: -------------------------------------------------------------------------------- 1 | ### General Object Destructuring Example 2 | 3 | ```js 4 | let myObj = { 5 | name: "Luke", 6 | age: 25, 7 | hobbies: "music" 8 | }; 9 | 10 | let { name, age, hobbies } = myObj; 11 | 12 | console.log(name, age, hobbies); // => Luke 25 music 13 | ``` 14 | 15 | Now the variables listed in between the curly braces are assigned the value of their respective properties in myObj. 16 | 17 | ### The order in which the variables are listed in the curly braces doesn’t matter. Additionally, we don’t have to list all the properties of an object if we only need one or two. 18 | 19 | ```js 20 | console.log(age, name, hobbies); // => 25 'Luke' 'music' 21 | 22 | console.log(hobbies, name, age); // => music Luke 25 23 | 24 | console.log(hobbies, name); // => music Luke 25 | 26 | ``` 27 | 28 | ### General Array Destructuring Example 29 | 30 | ```js 31 | let arr = [‘Jim’, ‘Bob’, ‘Sarah’, ‘Cassie’]; 32 | 33 | let [ jim, bob, sarah, cassie ] = arr; 34 | 35 | console.log(jim, bob, sarah, cassie); //outputs: Jim Bob Sarah Cassie 36 | ``` 37 | 38 | ## Unlike objects, the name we give the variables doesn’t matter. Let’s change the above example: So, each of the variable names will ONLY count for the index-positions I fetch. 39 | 40 | ```js 41 | let arr = [‘Jim’, ‘Bob’, ‘Sarah’, ‘Cassie’]; 42 | 43 | let [ var1, var2, var3, var4] = arr; 44 | 45 | console.log(var1, var2, var3, var4); //outputs: Jim Bob Sarah Cassie 46 | ``` 47 | 48 | ### If I include less variables then there are indexes in the arrays, then just like in Object-destructuring, only that many array element will be included in the returned array, starting from zero-index position and AGAIN without giving any meaning to the the name I give to the variables. So, each of the variable names will ONLY count for the index-positions I fetch. 49 | 50 | let arr = [‘Jim’, ‘Bob’, ‘Sarah’, ‘Cassie’]; 51 | 52 | let [ jim, bob, cassie ] = arr; 53 | 54 | console.log(jim, bob, cassie); //outputs: Jim Bob Sarah 55 | 56 | ## Using Spread operator - It is often used for splitting out a part of an object, but keeping the remaining properties in another object. 57 | 58 | ```js 59 | let myObj = { 60 | 61 | name: "Luke", 62 | age: 25, 63 | hobbies: "music" 64 | 65 | }; 66 | 67 | let { hobbies, ...rest } = myObj; // => Luke 25 music 68 | 69 | console.log(hobbies, rest) // => music { name: 'Luke', age: 25 } 70 | 71 | console.log(hobbies, rest.age) // => music 25 72 | 73 | ``` -------------------------------------------------------------------------------- /ES6/callback-hell-examples.js: -------------------------------------------------------------------------------- 1 | 2 | setTimeout((changeMaker) => { 3 | let list = changeMaker + ', '; 4 | 5 | setTimeout((changeMaker) => { 6 | list += changeMaker + ', '; 7 | 8 | setTimeout((changeMaker) => { 9 | list += changeMaker + ', '; 10 | 11 | setTimeout((changeMaker) => { 12 | list += changeMaker + ', '; 13 | 14 | setTimeout((changeMaker) => { 15 | list += changeMaker 16 | 17 | console.log(list); 18 | }, 1, 'Travis Kalanick'); 19 | }, 1, 'MarkZuckerberg'); 20 | }, 1, 'SteveWoz'); 21 | }, 1, 'SteveJobs'); 22 | }, 1, 'BillGates'); 23 | 24 | 25 | /* Looking at the above, setTimeout gets a callback function that executes after one millisecond. The last parameter just feeds the callback with data, i.e the argument 'changeMaker' . This is like an Ajax call except the return 'changeMaker' parameter would come from the server. 26 | 27 | I am gathering a list of changeMakers through asynchronous code. Each callback gives me a single 'changeMaker' name and I append that to the list. */ 28 | 29 | -------------------------------------------------------------------------------- /ES6/create-class-in-ES6.js: -------------------------------------------------------------------------------- 1 | class User { 2 | 3 | constructor (name, age) { 4 | this.name = name; 5 | this.age = age; 6 | } 7 | 8 | getUserData() { 9 | console.log(this.name + " is " + this.age + " years old."); 10 | } 11 | } 12 | 13 | let user = new User('paul', 18) 14 | user.getUserData() -------------------------------------------------------------------------------- /ES6/destructuring.js: -------------------------------------------------------------------------------- 1 | //Destructuring Example-1 2 | /* Destructuring allows us to extract data from arrays and objects into separate variables. 3 | 4 | Destructuring can also be used for passing objects into a function, allowing you to pull specific properties out of an object in a concise manner. It is also possible to assign default values to destructured arguments, which can be a useful pattern if passing in a configuration object. */ 5 | 6 | let jane = { firstName: 'Jane', lastName: 'Doe'}; 7 | let john = { firstName: 'John', lastName: 'Doe', middleName: 'Smith' } 8 | 9 | // the below pattern that I always use in React 10 | let sayName = ({firstName, lastName, middleName = "N/A"}) => { 11 | console.log(`Hello ${firstName} ${lastName} ${middleName}`); 12 | } 13 | 14 | // sayName(jane); // -> Hello Jane N/A Doe 15 | // sayName(john) // -> Hello John Doe Smith 16 | 17 | // Examples of array destructuring for function parameters: 18 | function foo ( [x, y] ) { 19 | console.log(x, y); 20 | } 21 | 22 | // foo([1,2]); // -> 1 2 23 | // foo([2]); // -> 2 undefined 24 | // foo([]) // -> undefined undefined 25 | 26 | 27 | // Examples of Object destructuring for parameters in function declaration: 28 | 29 | function foo ( { x, y } ) { 30 | console.log(x, y); 31 | } 32 | 33 | foo({y: 1, x: 2}) // -> 2 1 34 | 35 | foo({y: 1}) // -> undefined 1 36 | 37 | foo({}) // -> undefined undefined 38 | 39 | /* This technique is an approximation of named arguments, in that the properties on the object map to the destructured parameters of the same names. That also means that we get optional parameters (in any position) for free, as you can see leaving off the x "parameter" worked as we'd expect. */ 40 | 41 | 42 | //Destructuring Example-2 43 | 44 | let full_name =['John','Deo']; 45 | 46 | let [first_name,last_name]=full_name; 47 | 48 | console.log(first_name,last_name); 49 | // outputs John Deo -------------------------------------------------------------------------------- /ES6/every-method-of-Array.js: -------------------------------------------------------------------------------- 1 | /*every: 2 | 3 | callback is a predicate - it should return a truthy or falsy value 4 | callback answers: does this item meet your criteria? 5 | callback gets these arguments: item, index, list 6 | final return value: false after the first item that failed to meet your criteria, else true 7 | note: stops iterating once it receives a falsy value from your callback. 8 | example use case:*/ 9 | 10 | const allPositiveNumbers = [1 , 2, 3].every((item) => { 11 | return item > 0; 12 | }) 13 | 14 | console.log(allPositiveNumbers); -------------------------------------------------------------------------------- /ES6/fat-arrow-function.js: -------------------------------------------------------------------------------- 1 | setTimeout(function() { 2 | console.log("'setTimeout called") 3 | }, 1000) 4 | 5 | /* The function we pass as an argument to setTimeout is called an anonymous function because it doesn’t have a name. 6 | 7 | ES6 has introduced a slightly different syntax to define anonymous functions called the fat arrow syntax, with it we can re-write the above as: */ 8 | 9 | setTimeout(() => { 10 | console.log("Fat arrow fn in setTimeout called") 11 | }, 1000) 12 | 13 | // What if we wanted to pass an argument to the function? We can re-write the below normal function to one that uses the fat arrow syntax: 14 | 15 | let add = function(a,b) { 16 | return a + b; 17 | }; 18 | 19 | // Can now be written as: 20 | 21 | let add = (a,b) => a + b; 22 | 23 | // In the first example we write return a + b but in the fat arrow version we just wrote a + b. That’s because in the fat arrow syntax if it is on one line, the statement gets returned automatically without the need to use the return keyword. 24 | // There is no "thin arrow function". -------------------------------------------------------------------------------- /ES6/filter-implement-remove-duplicates.js: -------------------------------------------------------------------------------- 1 | // Problem-1 Filter even numbers 2 | 3 | let numberArray = [1,2,3,4,5,6,7,8,9,10]; 4 | 5 | let evenNumbers = []; 6 | 7 | for (let i = 0; i < numberArray.length; i++) { 8 | if (numberArray[i] % 2 === 0) { 9 | evenNumbers.push(numberArray[i]); 10 | } 11 | } 12 | // console.log(evenNumbers); 13 | 14 | let evenNumbersWithFilter = numberArray.filter((item) => (item % 2 === 0)); 15 | 16 | // console.log(evenNumbersWithFilter); 17 | 18 | 19 | // Problem 2:- Filter objects with tags javascript 20 | 21 | var persons = [ 22 | {id : 1, name : "John", tags : "javascript"}, 23 | {id : 2, name : "Alice", tags : "javascript"}, 24 | {id : 3, name : "Roger", tags : "java"}, 25 | {id : 4, name : "Adam", tags : "javascript"}, 26 | {id : 5, name : "Alex", tags : "java"} 27 | ]; 28 | 29 | let jsTags = persons.filter((item) => (item.tags === "javascript")) 30 | 31 | // console.log(jsTags); 32 | 33 | // Problem 2 with indexOf 34 | let jsTags2 = persons.filter((item) => (item.tags.indexOf("javascript") > -1)); 35 | 36 | // console.log(jsTags2); 37 | 38 | // Other example - traverses an array and inserts non-duplicate elements into a new array. That is, if an element is duplicated, then only insert that element once into the final newArray 39 | 40 | function findNonDuplicates (array) { 41 | let models = []; 42 | for(var i = 0; i < array.length; i++) { 43 | if(array.indexOf(array[i]) === i) { 44 | models.push(array[i]); 45 | } 46 | } 47 | return models; 48 | } 49 | 50 | let arr = [1, 2, 3, 4.4, 2]; 51 | // console.log(findNonDuplicates((arr))); 52 | 53 | // using filter 54 | function findNonDuplicatesFilter (array) { 55 | return array.filter((elem, index, arr) => { 56 | return array.indexOf(elem) === index; 57 | }) 58 | } 59 | 60 | // console.log(findNonDuplicatesFilter(arr)); 61 | 62 | // Write a function that returns the number of zeros in a given array? 63 | noOfZeros = arr => { 64 | return arr.filter(zero => (zero === 0)).length 65 | } 66 | 67 | console.log(noOfZeros([1, 2, 0, 0, 5])); 68 | 69 | -------------------------------------------------------------------------------- /ES6/find-method.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | find () - arguments explanation 4 | 5 | callback is a predicate - it should return a truthy or falsy value 6 | callback answers: is this item what you’re looking for? 7 | callback gets these arguments: item, index, list 8 | final return value: the item you’re looking for, or undefined 9 | note: stops iterating once it receives a truthy value from your callback. 10 | example use case 11 | 12 | 13 | findIndex: 14 | 15 | callback is a predicate - it should return a truthy or falsy value 16 | callback answers: is this item what you’re looking for? 17 | callback gets these arguments: item, index, list 18 | final return value: the index of the item you’re looking for, or -1 19 | note: stops iterating once it receives a truthy value from your callback. 20 | example use case:*/ 21 | 22 | 23 | // Examaple to find negaive number 24 | function findNegativeNum (elem) { 25 | return elem < 0; 26 | } 27 | 28 | let myArr = [1, 20, false, -2]; 29 | 30 | // find method returns first negative number found 31 | // console.log(myArr.find(findNegativeNum)); // -2 32 | 33 | // findIndex method returns index of first negative number located 34 | // console.log(myArr.findIndex(findNegativeNum)); // 3 35 | 36 | // example function to find non-numeric array values 37 | function findNonNum(elem) { 38 | return typeof elem !== 'number' ; 39 | } 40 | 41 | let myArr1 = [2, 27, 33.45, 'apple', 'yes', 0, 3.14]; 42 | 43 | // find method returns value of first non-numeric element 44 | // console.log(myArr1.find(findNonNum)); 45 | // findIndex returns location of first non-numeric element 46 | // console.log(myArr1.findIndex(findNonNum)); 47 | 48 | // another example array to search for non-numeric values 49 | let myArr3 = [1, 2, 3, 4.4]; 50 | 51 | // console.log(myArr3.find(findNonNum)); // returns undefined 52 | // console.log(myArr3.findIndex(findNonNum)); // returns -1 53 | 54 | 55 | const objects = [{ id: 'a' }, { id: 'b' }, { id: 'c' }]; 56 | 57 | const findIdWithb = objects.find((item) => { 58 | return item.id === 'b' 59 | }); 60 | 61 | console.log(findIdWithb); 62 | 63 | const findIdIndexWithb = objects.findIndex((item) => { 64 | return item.id === 'b' 65 | }); 66 | 67 | console.log(findIdIndexWithb); -------------------------------------------------------------------------------- /ES6/function-currying.js: -------------------------------------------------------------------------------- 1 | /* https://en.wikipedia.org/wiki/Currying 2 | 3 | n mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument. 4 | 5 | Currying is a process to reduce functions of more than one argument to functions of one argument with the help of lambda calculus. 6 | f(n, m) --> f'(n)(m) 7 | */ 8 | 9 | // simple add() funtion without currying 10 | add = (x, y) => x + y 11 | add(2, 3) // => 5 12 | 13 | // Now the same function in curryied form 14 | add_curried = x => y => x + y 15 | 16 | //in order to use our curried function, we have to call it a bit differently … This is because the first (outer) function call returns a second (inner) function. Only after we call the second function do we actually get the result. 17 | 18 | console.log(add_curried(2)(3)) // => 5 19 | 20 | // Here is the same code of curried function without arrow functions … 21 | let add_curried_ES5 = function (x) { 22 | return function(y) { 23 | return x + y 24 | } 25 | } 26 | 27 | console.log(add_curried_ES5(2)(3)) // => 5 28 | 29 | // SIMPLE EXPLANATION - Currying is the process of taking a function with multiple arguments and turning it into a sequence of functions each with only a single argument. 30 | 31 | const notCurry = (x, y, z) => x + y + z; // a regular function 32 | const curry = x => y => z => x + y + z; // a curry function 33 | 34 | // currying applied on a familiar JavaScript method and generating new functions using it: 35 | // First, normal implementation 36 | let myStr = "rohan" 37 | console.log(myStr.substr(0, 2)); // => ro 38 | 39 | // now curried implementation 40 | const curriedSubstr = start => length => str => str.substr(start, length) 41 | 42 | const getCurriedSubstr = (start, length, str) => curriedSubstr(start) (length) (str) 43 | 44 | console.log(getCurriedSubstr(0, 2, myStr)) // => ro 45 | 46 | -------------------------------------------------------------------------------- /ES6/map-Implementation-On-Objects.js: -------------------------------------------------------------------------------- 1 | // The map() method creates a new array with the results of calling a provided function on every element in this array. 2 | 3 | // Problem - 1 We’ve an array of products, that has two properties: `id` and `name`. I want to get all ids, wih map() method: 4 | 5 | let products = [ 6 | { 7 | id: 0, 8 | name: 'Product 1' 9 | }, 10 | { 11 | id: 1, 12 | name: 'Product 2' 13 | } 14 | ]; 15 | 16 | let productsIds = products.map((item) => { 17 | return item.id; 18 | }) 19 | 20 | // console.log(productsIds); 21 | 22 | /* Problem-2 23 | 24 | The map() mehod's syntax is as below 25 | 26 | let newArr = oldArr.map((val, index, arr) => { 27 | // return element to new Array 28 | }); 29 | 30 | newArr — the new array that is returned 31 | oldArr — the array to run the map function on 32 | val — the current value being processed 33 | index — the current index of the value being processed 34 | arr — the original array 35 | 36 | Create an object from a given array and the given array is as below 37 | [1,2,3,4]; 38 | 39 | */ 40 | 41 | let arr = [1,2,3,4]; 42 | 43 | let obj = arr.map((val, index, arr) => { 44 | return { 45 | VALUE : val, 46 | INDEX: index 47 | } 48 | }) 49 | 50 | // console.log(obj); 51 | 52 | // Problem-2 - Using map() return full name from the given array 53 | var oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}]; 54 | 55 | let newArr = []; 56 | 57 | oldArr.map((item, index) => { 58 | item.full_name = [item.first_name, item.last_name].join(' '); 59 | return item; 60 | }); 61 | console.log(oldArr); -------------------------------------------------------------------------------- /ES6/rest-spread.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohan-paul/Javascript-Common-Challenges-Problems/79fe5eb3f88cf35840e836fc9ca8d9fd7063f2c4/ES6/rest-spread.jpg -------------------------------------------------------------------------------- /ES6/rest-spread.js: -------------------------------------------------------------------------------- 1 | /* KEY POINT - The spread operator allows us to spread the value of an array (or any iterable) across zero or more arguments in a function or elements in an array (or any iterable). 2 | 3 | SO WITH SPREAD THING 'UNPACKING ELEMENTS' - Allowes an iterable (array, string, object) to be expanded where more arguments / elements are expected. 4 | 5 | The rest parameter allows us to pass an indefinite number of parameters to a function and access them in an array. So rest parameter is ONLY about when I am implementing argument passing mechanism in more compact way - Otherwise both take the same triple-dot (...) syntax 6 | Rest parameters must be at the end or it does not work 7 | 8 | SO WITH REST THING 'PACKING ELEMENTS' - Collects multiple elements and condenses them into a single eleme. 9 | 10 | */ 11 | 12 | // Example - Display the array of passed arguments. 13 | 14 | function printArguments(...theArguments) { 15 | console.log(theArguments); 16 | } 17 | 18 | printArguments("hi", "this", "is", "paul"); // => [ 'hi', 'this', 'is', 'paul' ] 19 | 20 | // Example - 2 - spreading object 21 | 22 | let spreadableObj = { 23 | key1: "value1", 24 | key2: "value2" 25 | }; 26 | 27 | let newObj = { 28 | ...spreadableObj, 29 | key3: "value3" 30 | }; 31 | 32 | console.log(newObj); // => { key1: 'value1', key2: 'value2', key3: 'value3' } 33 | 34 | // Example - 3 - Spreading Array 35 | 36 | //Combine two arrays. 37 | 38 | const spreadableOne = [1, 2, 3, 4]; 39 | const spreadableTwo = [5, 6, 7, 8]; 40 | 41 | const combinedArr = [...spreadableOne, ...spreadableTwo]; 42 | console.log(combinedArr); // => [ 1, 2, 3, 4, 5, 6, 7, 8 ] 43 | 44 | // Remove an array element without mutating the original array. From the below arrray remove 'salmon' and return the array - Great example, without using splice(), as splice() will mutate the original array 45 | 46 | const animals = ["squirrel", "bear", "deer", "salmon", "rat"]; 47 | 48 | const newArr = [...animals.slice(0, 3), ...animals.slice(4)]; 49 | 50 | console.log(newArr); // [ 'squirrel', 'bear', 'deer', 'rat' ] 51 | -------------------------------------------------------------------------------- /ES6/some-method-of-Array.js: -------------------------------------------------------------------------------- 1 | /*some: 2 | 3 | callback is a predicate - it should return a truthy or falsy value 4 | callback answers: does this item meet your criteria? 5 | callback gets these arguments: item, index, list 6 | final return value: true after the first item that meets your criteria, else false 7 | note: stops iterating once it receives a truthy value from your callback. 8 | example use case:*/ 9 | 10 | const hasNegativeNumber = [1, 2, 3, -4, 5].some((item) => { 11 | return item < 0; 12 | }) 13 | 14 | console.log(hasNegativeNumber); -------------------------------------------------------------------------------- /ES6/this-in-ES6/this-in-ES6_3.js: -------------------------------------------------------------------------------- 1 | // Regular function binding to global object's this 2 | 3 | function foo() { 4 | return console.log(this.a); // global 5 | } 6 | 7 | foo.a = 'func'; 8 | 9 | global.a = 'global-variable'; 10 | 11 | // note in above, I can not use var a = 'global' in my node environment, but can do so in the chrome dev-tool environment. Remember, in browser the global object is window and in node its 'global' 12 | 13 | 14 | foo(); // => global-variable 15 | 16 | /* 17 | The reason why above gave a console of global-variable, is because we mentioned earlier that this context for a function, is not decided by where it is declared, but by how and where it is called! Here, foo was called from the global context, and during its execution, this will be binded to the global object [Default binding rule], and since, regular functions and global object can only have this context, this context at the time of execution was pointing to the variable a declared in global scope, and hence the value was a was global and not func. 18 | 19 | */ 20 | 21 | // As expected and explained in ES_2.js file that below will output undefine, as arrow function does not have any this binding 22 | 23 | var obj_1 = { 24 | a : 'object???', 25 | foo_1 : () => { console.log(this.a) } 26 | }; 27 | 28 | obj_1.foo_1(); // undefined 29 | 30 | 31 | 32 | // Now, wrapping arrow within a function, would make the regular function to bind the object's this.a value 33 | 34 | var obj_2 = { 35 | 36 | a : 'object???', 37 | 38 | foo : function() { 39 | return (() => { 40 | console.log(this.a) 41 | })(); 42 | } 43 | }; 44 | 45 | obj_2.foo(); // object??? 46 | 47 | // 48 | 49 | -------------------------------------------------------------------------------- /ES6/this-in-ES6_3.js: -------------------------------------------------------------------------------- 1 | // Regular function binding to global object's this 2 | 3 | function foo() { 4 | return console.log(this.a); // global 5 | } 6 | 7 | foo.a = 'func'; 8 | 9 | global.a = 'global-variable'; 10 | 11 | // note in above, I can not use var a = 'global' in my node environment, but can do so in the chrome dev-tool environment. Remember, in browser the global object is window and in node its 'global' 12 | 13 | 14 | foo(); // => global-variable 15 | 16 | /* 17 | The reason why above gave a console of global-variable, is because we mentioned earlier that this context for a function, is not decided by where it is declared, but by how and where it is called! Here, foo was called from the global context, and during its execution, this will be binded to the global object [Default binding rule], and since, regular functions and global object can only have this context, this context at the time of execution was pointing to the variable a declared in global scope, and hence the value was a was global and not func. 18 | 19 | */ 20 | 21 | // As expected and explained in ES_2.js file that below will output undefine, as arrow function does not have any this binding 22 | 23 | var obj_1 = { 24 | a : 'object???', 25 | foo_1 : () => { console.log(this.a) } 26 | }; 27 | 28 | obj_1.foo_1(); // undefined 29 | 30 | 31 | 32 | // Now, wrapping arrow within a function, would make the regular function to bind the object's this.a value 33 | 34 | var obj_2 = { 35 | 36 | a : 'object???', 37 | 38 | foo : function() { 39 | return (() => { 40 | console.log(this.a) 41 | })(); 42 | } 43 | }; 44 | 45 | obj_2.foo(); // object??? 46 | 47 | // 48 | 49 | -------------------------------------------------------------------------------- /Functional-Programming/1.js: -------------------------------------------------------------------------------- 1 | /* Return everything 2 | Everything should return, also functions that emit side-effects. Try to preserve homomorphism. Try to keep the return type of a function consistent. Don't mix computations that transform data with things like writing to screen. Modular code is easier to maintain. Use parameters for replaceable data instead of hard-coding. */ 3 | 4 | // Implementation of the above with examples by first using non-best-practice way to return factorial of no-5 5 | 6 | let fact = 1; 7 | 8 | for (let i = 1; i <= 5; i++ ) { 9 | fact *= i; 10 | } 11 | 12 | console.log('Fact of 5: ', fact); 13 | 14 | //Now the best practice 15 | 16 | const factorial = n => 17 | n === 0 ? 1 : n * factorial(n - 1); 18 | 19 | console.log('Factorial of 5 is : ', factorial(5)); 20 | 21 | -------------------------------------------------------------------------------- /Functional-Programming/max.js: -------------------------------------------------------------------------------- 1 | // require _ from ('underscore'); 2 | 3 | var _ = require('underscore'); 4 | 5 | console.log(_.max([1, 2, 3, 4, 5])); 6 | 7 | /* Write a function named plucker() that takes a key into an associative structure—such as an array or an object and returns a function that, given a structure, returns the value at the key. */ 8 | 9 | function plucker (key) { 10 | return function (obj) { 11 | return (obj && obj[key]); 12 | } 13 | } 14 | 15 | //Use case 16 | var best = {title: "Infinite Jest", author: "DFW"}; 17 | 18 | var getTitle = plucker('title'); 19 | // console.log(getTitle(best)); // Infinite Jest 20 | 21 | // Note, getTitle itself is a function because plucker() returns a function as its first return and that takes an argument. 22 | 23 | // another use case 24 | var books = [{title: "Chthon"}, {stars: 5}, {title: "Botchan"}]; 25 | 26 | var third = plucker(2); 27 | console.log(third(books)); // { title: 'Botchan' } 28 | 29 | 30 | -------------------------------------------------------------------------------- /Functional-Programming/pure_functions.js: -------------------------------------------------------------------------------- 1 | // 1>> Combine multiple arrays into one array. 2 | combine = (...arrays) => [].concat(...arrays); 3 | 4 | // console.log(combine(["foo"], ["bar", "baz"], [1, 2])) // => ["foo", "bar", "baz", 1, 2] 5 | 6 | 7 | // 2>> compact(array) - Returns a copy of the array with all falsy values removed. 8 | // compact([0, 1, false, 2, "", 3]) // => [1, 2, 3] 9 | 10 | compact = arr => arr.filter(i => i) 11 | 12 | // console.log(compact([0, 1, false, 2, "", 3])); 13 | 14 | //Alternative 2 15 | compact2 = arr => arr.filter(Boolean) 16 | // console.log(compact2([0, 1, false, 2, "", 3])); 17 | 18 | /* contains(array, value) - Returns true if the value is present in the array. 19 | 20 | contains([1, 2, 3], 3) // => true */ 21 | 22 | contains = (() => Array.prototype.includes 23 | ? (arr, value) => arr.includes(value) 24 | : (arr, value) => arr.some(elem => elem === value) 25 | )(); 26 | 27 | console.log(contains([1, 2, 3], 3)); -------------------------------------------------------------------------------- /General-JS-Problems/Pi-To-n-th-digits.js: -------------------------------------------------------------------------------- 1 | /* 2 | Find PI to the Nth Digit - Enter a number and have the program generate PI up to that many decimal places. Keep a limit to how far the program will go. 3 | 4 | Based on John Machin's formula pi/4 = 4 * arctan (1/5) - arctan (1/239) 5 | */ 6 | 7 | findPI_ToNthDigits = n => { 8 | 9 | if (n === undefined || n > 20) { 10 | n = 20 11 | } 12 | 13 | return (16 * Math.atan(1/5) - 4 * (Math.atan(1/239))) 14 | } 15 | 16 | console.log(findPI_ToNthDigits(20)); 17 | -------------------------------------------------------------------------------- /General-JS-Problems/atoi-string-to-Number-2.js: -------------------------------------------------------------------------------- 1 | /* Convert a string to an integer in C, JavaScript, and Ruby 2 | 3 | Some Theory - A> The number system ranges from 48 to 59 in chartCodeAt() method 4 | 5 | console.log("0".charCodeAt("0")); // 48 6 | console.log("9".charCodeAt("0")); // 57 7 | 8 | B> JavaScript's highest integer value that a number can go to without losing precision? - he max safe integer is 231-1, or 2147483647. 9 | */ 10 | 11 | // SOLUTION WITHOUT USING REGEXP AND PARSEINT 12 | 13 | myAtoi = str => { 14 | 15 | let i = 0, numSign = '+', number = '', finalOutputNum = 0, base10Multiplier = 1; 16 | 17 | str = str.trim() // remove all whitespaces from both ends 18 | 19 | // First move i forward and update sign to take up '-' if '-' is found 20 | // And if a '+' is found just treat it, as if there was nothing before the number and check-out the next number to start building the number with the next loop 21 | if (str[0] === '+') { 22 | i++ 23 | } else if (str[0] === '-') { 24 | numSign = '-' 25 | i++ 26 | } 27 | 28 | // For the above code, I could just use Regexp, like my other solution in my other file. 29 | 30 | // Now traverse through the given string argument and build the number string. 31 | 32 | for (i ; i < str.length; i++) { 33 | 34 | if (str[i].charCodeAt(0) >= 48 && str[i].charCodeAt(0) <= 57) { 35 | number += str[i] 36 | } else { 37 | if (number === "") { 38 | return 0 39 | } else { 40 | break; 41 | } 42 | } 43 | } 44 | 45 | // From the above I have a string "number". Now without using parseInt() I will convert it to an integer 46 | for (i = (number.length - 1); i >=0; i--) { 47 | 48 | finalOutputNum += base10Multiplier * number[i]; 49 | base10Multiplier *= 10; 50 | 51 | if ( finalOutputNum > 2147483647 && numSign === '+' ) { 52 | return 2147483647 53 | } else if (finalOutputNum > 2147483648 && numSign === '-' ) { 54 | return -2147483648; 55 | } 56 | } 57 | 58 | return ( numSign === '-' ? (-1 * finalOutputNum) : finalOutputNum ) 59 | 60 | } 61 | 62 | console.log(myAtoi("+1")); // => 1 -------------------------------------------------------------------------------- /General-JS-Problems/calculate-log-recursively.js: -------------------------------------------------------------------------------- 1 | function logBase2 (num ) { 2 | if ( num == 1) { 3 | return 0; 4 | } else { 5 | return (1 + logBase2( num / 2)); 6 | } 7 | } 8 | 9 | /* The formulae:- 10 | 11 | log(num) to base 2 = y 12 | 13 | means mathematically 14 | 15 | 2^y = num 16 | */ 17 | 18 | console.log(logBase2(16)); // Should output 4 19 | 20 | /* Explanation 21 | 22 | function logBase2(16); 23 | 24 | = 1 + logBase2 (16 / 2) >> 1 + ( 1 + logBase2(8)) 25 | 26 | = 1 + ( 1 + ( 1 + logBase2 (4)) 27 | 28 | = 1 + ( 1 + ( 1 + (1 + logBase2(2)))); 29 | 30 | = 1 + ( 1 + (1 + (1 + (logBase (1))))) // Here the abort-condition is reached and the loop stops, as logBase2(1) returns 0 31 | 32 | = 1 + 1 + 1 + 1 + 0 = 4 33 | 34 | 35 | */ -------------------------------------------------------------------------------- /General-JS-Problems/check-nonEmptyString.js: -------------------------------------------------------------------------------- 1 | // Problem - You want to verify (assume its called 'unknownVariable') that a variable is defined, is a string, and is not empty. 2 | 3 | if(((typeof unknownVariable !== 'undefined' && unknownVariable) && 4 | unknownVariable.length() > 0) && 5 | typeof unknownVariable.valueOf() == 'string') 6 | -------------------------------------------------------------------------------- /General-JS-Problems/comparing-number-to-string.txt: -------------------------------------------------------------------------------- 1 | Question 2 of 56 2 | 3 | What will be the result of the following line of JavaScript code? 4 | var result = "a" < 3; 5 | alert(result); 6 | Support your answer with detailed reasoning. Be as explicit as possible. 7 | 8 | var result = "a" < 3; 9 | alert(result); 10 | 11 | Will output - false 12 | 13 | JavaScript defines >= and <= (and several other operators) in a way that allows them to coerce their operands to different types. It's just part of the definition of the operator. 14 | 15 | In the case of <, >, <=, and >= check §11.8.5 of the specification. 16 | 17 | If both operands are strings (after having been coerced from objects, if necessary), it does a string comparison. 18 | 19 | Otherwise, it coerces the operands to numbers and does a numeric comparison. 20 | 21 | This works because of typecasting and the fact that NaN < 3 is false. 22 | 23 | When applying to the < operator, both operands are cast to Numbers, so that comparison becomes 24 | 25 | Number("string") < 3 26 | 27 | which is equivalent to NaN < 3 which evaluates to false 28 | 29 | 30 | Question 14 of 56 31 | 32 | var num = -10; 33 | alert(num.toString(2)); 34 | 35 | Will output >> -1010 36 | 37 | The toString() function is used with a number num as shown in above syntax using the ‘.’ operator. This function will convert num to a string. 38 | 39 | Parameters Used: This function accepts a single optional parameter base. This parameter specifies the base in which the integer is represented in string. It is an integer between 2 and 36 which is used to specify the base for representing numeric values. -------------------------------------------------------------------------------- /General-JS-Problems/convert-word-to-integer-atoi.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohan-paul/Javascript-Common-Challenges-Problems/79fe5eb3f88cf35840e836fc9ca8d9fd7063f2c4/General-JS-Problems/convert-word-to-integer-atoi.js -------------------------------------------------------------------------------- /General-JS-Problems/count-vowels.js: -------------------------------------------------------------------------------- 1 | /* Find the count of Vowels in the given string using match method and regular expression in JS 2 | */ 3 | 4 | //The match() method searches a string for a match against a regular expression, and returns the matches, as an Array object. 5 | 6 | function countVowels(str) { 7 | const re = /(a|e|i|o|u)/g 8 | 9 | let vowelCounter = 0 10 | 11 | for (let i of str) { 12 | if (i.match(re)) { 13 | vowelCounter++ 14 | } 15 | } 16 | return vowelCounter 17 | } 18 | 19 | // console.log(countVowels("Paul")); // => 2 20 | 21 | // Alternative - 2 22 | countVowels2 = str => { 23 | let vowelCounter = str.match(/[aeiou]/gi) 24 | return vowelCounter === null 25 | ? "No vowels in the given string" 26 | : vowelCounter.length 27 | } 28 | 29 | // console.log(countVowels2("Psfsfl")); 30 | 31 | const countVowels3 = str => str.match(/[aeiou]/gi).length 32 | 33 | // console.log(countVowels3("Paul")); 34 | 35 | countVowels4 = str => { 36 | return Array.from(str).filter(vowelsInStr => "aeiou".includes(vowelsInStr)) 37 | .length 38 | } 39 | 40 | // The includes() method determines whether an array includes a certain value among its entries, returning true or false as appropriate. 41 | 42 | console.log(countVowels4("Paul")) 43 | -------------------------------------------------------------------------------- /General-JS-Problems/factorial-Performance-Recursive-vs-Iterative.js: -------------------------------------------------------------------------------- 1 | function factorial_Recursive(num) { 2 | return (num === 1 ? 1 : num * factorial_Recursive(num - 1)); 3 | } 4 | 5 | 6 | function factorial_Iterative(num) { 7 | if (num < 0 ) { 8 | return 'undefined'; 9 | } 10 | var fact = 1; 11 | 12 | for (var i = num; i > 0; i--) { 13 | fact *= i; 14 | } 15 | return fact; 16 | } 17 | 18 | console.time("fact_recursive"); 19 | factorial_Recursive(1000); 20 | console.timeEnd("fact_recursive"); 21 | 22 | console.log("*******************************"); 23 | 24 | console.time("fact_Iterative"); 25 | factorial_Iterative(1000); 26 | console.timeEnd("fact_Iterative"); 27 | 28 | console.log("*******************************"); 29 | 30 | // Cool version to make factorial 31 | const factorial_cool = n => 32 | [...Array(n + 1).keys()].slice(1).reduce((x, y) => x * y); 33 | 34 | console.log(factorial_cool(4)); // => 24 35 | -------------------------------------------------------------------------------- /General-JS-Problems/fibonacci-number-GOOD-Future-Ref.js: -------------------------------------------------------------------------------- 1 | // Problem-1 - Find the n-th fibonacci number iteratively (using ES6 destructuring) - BEST LOOKING STANDARD SOLUTION WITH DESTRUCTURING 2 | n_th_fibonacci = n => { 3 | let [a, b] = [0, 1] 4 | 5 | while (--n) { 6 | ;[a, b] = [b, b + a] 7 | } 8 | return b 9 | } 10 | 11 | console.log(n_th_fibonacci(10)) // => 55 12 | 13 | /* Explanation of the above - The two numbers a and b are initialized as 1 and 0, and in every iteration of the loop (counting backwards from n to 0), b becomes the sum of the two numbers ( its current value and prrevious value of the series ) and the lower number a becomes the previous value of the higher number b. When n reaches 0, the higher of the two numbers is returned and, it resolves to the nth number in the Fibonacci sequence. 14 | 15 | Note, that the condition while (--num) is equivalent to while (num > 0) because as soon as --num becomes zero, i.e. "false" the while loop no more get executed 16 | */ 17 | 18 | /* Problem-2 - Return a full fibonacci series upto a specified positon (e.g. upto the 10th Fibonacci number in the Fibonacci series) as an array. every number after the first two is the sum of the two preceding ones 19 | So the final series will look like below (so the 10 th fibonacci is 55) 20 | 21 | position = 1 2 3 4 5 6 7 8 9 10 22 | FibNumber = 1 1 2 3 5 8 13 21 34 55 23 | 24 | GOOD STANDARD SOLUTION-Refer to this for general implementation - (following the same approach as above solution) - 25 | */ 26 | n_th_fibonacci = n => { 27 | let [a, b] = [0, 1] 28 | let fibSeries = [1] 29 | 30 | while (--n) { 31 | ;[a, b] = [b, b + a] 32 | fibSeries.push(b) 33 | } 34 | return fibSeries 35 | } 36 | 37 | console.log(n_th_fibonacci(10)) // => [ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ] 38 | -------------------------------------------------------------------------------- /General-JS-Problems/fibonacci-sum-odd.js: -------------------------------------------------------------------------------- 1 | /* Problem Statement - 2 | Return the sum of all odd Fibonacci numbers up to and including the passed number if it is a Fibonacci number. 3 | 4 | The first few numbers of the Fibonacci sequence are 1, 1, 2, 3, 5 and 8, and each subsequent number is the sum of the previous two numbers. As an example, passing 4 to the function should return 5 because all the odd Fibonacci numbers under 4 are 1, 1, and 3.*/ 5 | 6 | addOddFibonacciNum = num => { 7 | let a = 0, b = 1, fib = 1, fibOddSum = 1; 8 | 9 | while ( a + b <= num ) { 10 | f = a + b; 11 | b = f; 12 | a = f - a; 13 | 14 | if ( f % 2 !== 0) { 15 | fibOddSum += f; 16 | } 17 | } 18 | return fibOddSum; 19 | } 20 | 21 | console.log(addOddFibonacciNum(4)); // => 5 -------------------------------------------------------------------------------- /General-JS-Problems/find_number_appearing-twice.js: -------------------------------------------------------------------------------- 1 | /* 2 | I have a list where every number in the range 1....n appears 3 | once except for one number which appears twice. 4 | Write a function for finding the number that appears twice. 5 | */ 6 | 7 | // METHOD 1: runtime = O(n) & memory = O(n) 8 | findDup = (list, n) => { 9 | let obj = {} 10 | let currentElem 11 | 12 | for (let i = 0; i < list.length; i++) { 13 | currentElem = list[i] 14 | if (obj[currentElem]) { 15 | return currentElem 16 | } else { 17 | obj[currentElem] = true 18 | } 19 | } 20 | } 21 | // so the above function will only return the fist occuring duplicate no 22 | 23 | myList = [1, 4, 2, 3, 4, 5, 6, 7, 8, 9, 10] 24 | 25 | // console.log(findDup(myList)); 26 | 27 | /* METHOD 2: runtime = O(n) & memory = O(1) 28 | Using the arithmetic sum formulae 29 | Note the Arithmetic Sum formulae is (n*(n + 1))/2 i.e. (n2 + n)/2 30 | */ 31 | 32 | findDupAlt = (list, n) => { 33 | let arithmeticSum = (n * n + n) / 2 34 | let sumList = 0 35 | for (let i of list) { 36 | sumList += i 37 | } 38 | return sumList - arithmeticSum 39 | } 40 | 41 | console.log(findDupAlt(myList, 10)) 42 | -------------------------------------------------------------------------------- /General-JS-Problems/form-largest-number-from-given-array.js: -------------------------------------------------------------------------------- 1 | /* Given an array of non negative integers,arrange them such that they form the largest number. 2 | Sample input: 3 | [3, 30, 34, 5, 9], 4 | 5 | Output number is 9534330. 6 | 7 | (Note: The result may be very large, so you can to return a string instead of an integer if that's required)* 8 | */ 9 | 10 | /* Algo - https://www.geeksforgeeks.org/given-an-array-of-numbers-arrange-the-numbers-to-form-the-biggest-number/ 11 | 12 | The idea is to use any comparison based sorting algorithm. In the used sorting algorithm, instead of using the default comparison, write a comparison function myCompare() and use it to sort numbers. 13 | 14 | Given two numbers X and Y, how should myCompare() decide which number to put first – we compare two numbers XY (Y appended at the end of X) and YX (X appended at the end of Y). If XY is larger, then X should come before Y in output, else Y should come before. For example, let X and Y be 542 and 60. To compare X and Y, we compare 54260 and 60542. Since 60542 is greater than 54260, we put Y first. 15 | */ 16 | 17 | /* To match the output of 9534330, looks like, the problem asks that we can not change a single number in the given array, that is, from the given array [3, 30, 34, 5, 9] - a 30 and 34 should remain as 30 and 34 - hence my solution below */ 18 | 19 | largestNum = arr => arr.map(String).sort((a, b) => (b+a) - (a+b)).reduce((accum, elem) => (accum + elem) ,'') 20 | 21 | console.log(largestNum([3, 30, 34, 5, 9])); // => 9534330 22 | 23 | /* Explanation of the part < sort((a, b) => (b+a) - (a+b)) > 24 | 25 | Here, I am just comparing a special combination of a, b (instead of a and b directly) - i.e. a special combination of each pair of elements in an array - before deciding how to sort them. So, like the explanation in geeksforgeeks, that I am just using a custom compare function. 26 | 27 | If XY is larger, then X should come before Y in output, else Y should come before. 28 | 29 | So, here, the sort function will take each pair of elements from the Array, and which way of placing them side-by-side is givng the larger number. e.g. for the pair 5 and 34, it will check if 534 is larger or 345 is larger. 30 | 31 | And because 534 is larger, it will place then accordingly. 32 | 33 | */ -------------------------------------------------------------------------------- /General-JS-Problems/function_chaining-call-function-inside-another-as-object-property.js: -------------------------------------------------------------------------------- 1 | /* Write a function func1 which will call another function func2 as a object property. Tat is I should be able to run func1()func2() . 2 | 3 | The purpose of this exercise is to understand how most of the function calls work in node.js. Like the below one 4 | 5 | var http = require('http'); 6 | http.createServer(function (req, res) { 7 | res.writeHead(200, {'Content-Type' : 'text/plain'}); 8 | res.write('Hello World'); 9 | res.end(); 10 | }).listen(3000); 11 | 12 | 13 | And in the above, what exactly is happening is - 14 | 15 | http.createServer().listen(); 16 | 17 | Where http is an object, and I am chaining createServer() and listen() to that 18 | 19 | */ 20 | 21 | function func1() { 22 | return { 23 | func2: () => { 24 | console.log("Inside func2"); 25 | return { 26 | func3: () => { 27 | console.log("Inside func3"); 28 | } 29 | } 30 | } 31 | } 32 | } 33 | 34 | func1().func2().func3(); -------------------------------------------------------------------------------- /General-JS-Problems/greatest_common_divisor.js: -------------------------------------------------------------------------------- 1 | // Find the greatest common divisor of two numbers 2 | function greatestCommonDivisor(a, b) { 3 | var divisor = 2, 4 | greatestDivisor; 5 | 6 | if ( a < 2 || b < 2) 7 | return 1; 8 | 9 | while (a >= divisor && b >= divisor) { 10 | if( a % divisor == 0 && b % divisor == 0) { 11 | greatestDivisor = divisor; 12 | } 13 | divisor++; 14 | } 15 | return greatestDivisor; 16 | } 17 | 18 | console.log(greatestCommonDivisor(14, 21)); -------------------------------------------------------------------------------- /General-JS-Problems/ifPowerOfFour.js: -------------------------------------------------------------------------------- 1 | // Check if a number is any power of 4. Its the same logic as checking if a number is power of 2. See my file small-snippets.js 2 | /* Notes - Keep dividing the number by 4, i.e, do n = n/4 iteratively until n becomes 1. In any iteration, if n%2 becomes non-zero and n is not 1 then n is not a power of 4. Otherwise is a power of 2. */ 3 | var isPowerOfFour = function (num) { 4 | while ( num != 1) { 5 | num = (num / 4); 6 | 7 | if ( num % 4 != 0 && num != 1) { 8 | return false; 9 | } 10 | }; 11 | return true; 12 | }; 13 | 14 | // We are checking with num != 1 because 1 can be the result of any number raised to power of 0 15 | console.log(isPowerOfFour(18)); 16 | 17 | // Check if the a number (1st argument) is a power of another number (the second argument) 18 | var isPower = function (num, n) { 19 | while ( num != 1) { 20 | num = (num / n); 21 | 22 | if ( num % n != 0 && num != 1) { 23 | return false; 24 | } 25 | }; 26 | return true; 27 | }; 28 | 29 | // We are checking with num != 1 because 1 can be the result of any number raised to power of 0 30 | console.log(isPower(16, 2)); -------------------------------------------------------------------------------- /General-JS-Problems/integer_length.js: -------------------------------------------------------------------------------- 1 | /* Write a function that takes an integer as input and returns the number of digits in that integer.*/ 2 | 3 | function integerLength(num) { 4 | return ('' + (num | 0)).length; 5 | } 6 | 7 | console.log(integerLength()); -------------------------------------------------------------------------------- /General-JS-Problems/isNumeric.js: -------------------------------------------------------------------------------- 1 | /* Write a JavaScript function to check whether a variable is numeric or not. 2 | 3 | Test Data: 4 | console.log(is_Numeric(12)); 5 | console.log(is_Numeric('abcd')); 6 | console.log(is_Numeric('12')); 7 | console.log(is_Numeric(' ')); 8 | console.log(is_Numeric(1.20)); 9 | console.log(is_Numeric(-200)); 10 | 11 | Output: 12 | true 13 | false 14 | true 15 | false 16 | true 17 | true */ 18 | 19 | is_Numeric = (num) => { 20 | return !isNaN(parseFloat(num)) && isFinite(num); 21 | } 22 | 23 | console.log(is_Numeric(12)); 24 | console.log(is_Numeric('abcd')); 25 | console.log(is_Numeric('12')); 26 | console.log(is_Numeric(' ')); 27 | console.log(is_Numeric(1.20)); 28 | console.log(is_Numeric(-200)); -------------------------------------------------------------------------------- /General-JS-Problems/isPalindrome.js: -------------------------------------------------------------------------------- 1 | // Implement a isPalindrome function with class constructor 2 | function Palindrome(str) { 3 | this.str = str 4 | } 5 | 6 | Palindrome.prototype.isPalindrome = function(str) { 7 | this.str = str 8 | 9 | let cleanStr = str.toLowerCase().replace(/[^a-zA-Z0-9]/gi, "") 10 | 11 | let len = cleanStr.length 12 | 13 | for (let i = 0; i < len / 2; i++) { 14 | if (cleanStr[i] !== cleanStr[len - 1 - i]) { 15 | return false 16 | } 17 | } 18 | return true 19 | } 20 | 21 | console.log(Palindrome.prototype.isPalindrome("eye")) 22 | 23 | console.log("eye".Palindrome.prototype.isPalindrome()) 24 | -------------------------------------------------------------------------------- /General-JS-Problems/isUgly.js: -------------------------------------------------------------------------------- 1 | /*https://www.geeksforgeeks.org/ugly-numbers/ 2 | 3 | Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7. 4 | Note that 1 is typically treated as an ugly number. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, … shows the first 11 ugly numbers. By convention, 1 is considered to be ugly number. 5 | */ 6 | 7 | /* Solution Algo - To check if a number is ugly, divide the number by greatest divisible powers of 2, 3 and 5, if the number becomes 1 then it is an ugly number otherwise not. 8 | 9 | Let's take an example : N=9000 (We want to check this number is ugly or not) , but for that we have to check it by dividing N by the Greatest Divisible Power of prime ( 2,3 or 5) : 10 | N=9000 = 2^3 * 3^2 * 5^3 11 | So, GDP of 2 becomes - 2^3 = 8 12 | GDP of 3 becomes - 3^2 = 9 13 | GDP of 5 becomes - 5^3=125 14 | 15 | 16 | */ 17 | 18 | isUgly = (num) => { 19 | 20 | if (num < 0) return false; 21 | if (num === 1) return true; 22 | 23 | while (num % 2 === 0 ) { num /= 2} 24 | while (num % 3 === 0 ) { num /= 3} 25 | while (num % 5 === 0 ) { num /= 5} 26 | 27 | return num === 1; 28 | } 29 | 30 | 31 | 32 | console.log(isUgly(9000)); -------------------------------------------------------------------------------- /General-JS-Problems/largest-Numbe-in-Array.js: -------------------------------------------------------------------------------- 1 | // Problem statement - Find Second largest element in an array 2 | function largest (arr) { 3 | return arr.reduce((a, b) => { 4 | return a > b ? a : b; 5 | }); 6 | } 7 | 8 | function largest2 (arr) { 9 | return arr.reduce((a, b) => { 10 | return Math.max(a, b); 11 | }) 12 | } 13 | 14 | // Finding max and min value from first priciple. Much faster than Math.max.apply. 15 | function largest3 (arr) { 16 | let max = 0; 17 | 18 | for (i= 0; i < arr.length; i++) { 19 | if (arr[i] > max) { 20 | max = arr[i]; 21 | } 22 | } 23 | return max; 24 | } 25 | 26 | 27 | // Using for..of syntax of ES6 28 | function largest4(arr) { 29 | let max = 0; 30 | for (let variable of arr) { 31 | if (variable > max) { 32 | max = variable; 33 | } 34 | } 35 | return max; 36 | } 37 | 38 | // Using spread operaton 39 | function largest5 (arr) { 40 | return Math.max(...arr); 41 | } 42 | 43 | console.log(largest4([1, 4, 3, 2])); -------------------------------------------------------------------------------- /General-JS-Problems/largest_product_yielded_ from_three_ integers.js: -------------------------------------------------------------------------------- 1 | /* Given an array of integers, find the largest product yielded from three of the integers */ 2 | 3 | -------------------------------------------------------------------------------- /General-JS-Problems/max-min-from-array-of-objects.js: -------------------------------------------------------------------------------- 1 | /*Finding Minimum and Maximum values in an Array of Objects 2 | 3 | We have an array of objects like below in the variable called data 4 | 5 | [ 6 | {x: 1, y: 14830}, 7 | {x: 2, y: 85055}, 8 | {x: 3, y: 03485}, 9 | {x: 4, y: 57885}, 10 | // ... 11 | ] 12 | 13 | Build two function calls — one for the minimum Y value, and one for the maximum Y value. 14 | 15 | */ 16 | 17 | // first create the variable data which is an array of objects with random set of 1000 records 18 | 19 | const data = []; 20 | for (let x = 0; x < 1000; x++) { 21 | data.push({ x: x, y: Math.floor(Math.random() * 1000) }); 22 | } 23 | // console.log(data); 24 | 25 | // Note in the below function the accumulator is the the variable minY and the first value of this is set to be data[0].y 26 | 27 | function getMinYValue () { 28 | return data.reduce((minY, thisObj) => thisObj.y < minY ? thisObj.y : minY, data[0].y) 29 | } 30 | 31 | function getMaxYValue() { 32 | return data.reduce((maxY, thisObj) => thisObj.y > maxY ? thisObj.y : maxY, data[0].y); 33 | } 34 | 35 | // Using Map and spread operaton. First get all the y values from each of the objects within data. 36 | 37 | function getYOnly () { 38 | return data.map( YVal => YVal.y ); 39 | } 40 | 41 | 42 | function getMinValueAlt () { 43 | return Math.min(...getYOnly()); 44 | } 45 | 46 | function getMaxValueAlt () { 47 | return Math.max(...getYOnly()); 48 | } 49 | 50 | console.log(getMaxValueAlt()); 51 | 52 | console.log(getMinValueAlt()); -------------------------------------------------------------------------------- /General-JS-Problems/max-product-three-elements.js: -------------------------------------------------------------------------------- 1 | // Given an array of integers, find the largest product yielded from three of the integers 2 | 3 | /* Algo - 4 | 5 | Sort the given array in ascending order and you have to take the maximum of these cases to get the answer.. 6 | 7 | Product of last 3 numbers in sorted array 8 | Product of first two and last number in the sorted array 9 | 10 | */ 11 | 12 | maxProductOfThreeeElem = (arr) => { 13 | 14 | let sortedArr = arr.sort((a, b) => a - b); 15 | 16 | // Greatest product is either (min1 * min2 * max1 || max1 * max2 * max3) 17 | 18 | let product1 = 1, product2 = 1, len = arr.length - 1; 19 | 20 | product1 = sortedArr[0] * sortedArr[1] * sortedArr[len]; 21 | 22 | for (let i = len; i > len - 3; i-- ) { 23 | product2 *= sortedArr[i]; 24 | } 25 | 26 | return Math.max(product1, product2) 27 | } 28 | 29 | console.log(maxProductOfThreeeElem([1,2,3,4])); // => 12 30 | console.log(maxProductOfThreeeElem([-4,2,3,1])); // => 12 31 | console.log(maxProductOfThreeeElem([-4,-2,-3,1])); // => 12 -------------------------------------------------------------------------------- /General-JS-Problems/median-of-Array.js: -------------------------------------------------------------------------------- 1 | /* Calculate the median of an array with javascript . faced this in Techolution Interview on 21-June-2018. Below was my solution at Techolution and it was indeed correct 2 | 3 | example; input = [1,2,3,4,5] 4 | output = 3 5 | 6 | input = [4,5,6,1,2,3] 7 | output = 3.5 */ 8 | 9 | median = arr => { 10 | 11 | let sortedArr = arr.sort((a, b) => a - b); 12 | 13 | let len = sortedArr.length; 14 | 15 | if (sortedArr.length % 2 !== 0) { 16 | let index1 = Math.floor(len / 2) 17 | return sortedArr[index1]; 18 | } else { 19 | let index2 = len / 2; 20 | return (((sortedArr[index2] + sortedArr[index2 - 1]) / 2).toFixed(1)); 21 | } 22 | } 23 | 24 | var input1 = [1,2,3,4,5]; 25 | var input2 = [4,5,6,1,2,3]; 26 | 27 | console.log(median(input1)); 28 | 29 | console.log(median(input2)); 30 | 31 | /* https://www.geeksforgeeks.org/median-of-stream-of-running-integers-using-stl/ 32 | Median can be defined as the element in the data set which separates the higher half of the data sample from the lower half. In other words we can get the median element as, when the input size is odd, we take the middle element of sorted data. If the input size is even, we pick average of middle two elements in sorted stream. */ -------------------------------------------------------------------------------- /General-JS-Problems/merge_two_sorted_array.js: -------------------------------------------------------------------------------- 1 | // merge two sorted array into a single sorted array 2 | 3 | /*Solution steps 4 | 5 | */ 6 | /*function mergeSortedArray(a, b) { 7 | for (var i = 0; i < b.length; i++) { 8 | a.push(b[i]); 9 | } 10 | for (i = 0; i < a.length; i++) { 11 | for(var j = i+1; j < a.length; j++ ) 12 | { 13 | if(a[i] > a[j]) { 14 | var temp = a[i]; 15 | a[i] = a[j]; 16 | a[j] = temp; 17 | } 18 | } 19 | 20 | } 21 | return a; 22 | }*/ 23 | 24 | function mergeSortedArray(a, b) { 25 | var sorted = [], 26 | indexA = 0, 27 | indexB = 0; 28 | 29 | while (indexA < a.length && indexB < b.length) { 30 | if (sortFn(a[indexA], b[indexB]) > 0) { 31 | sorted.push(b[indexB++]); 32 | } else { 33 | sorted.push(a[indexA++]) 34 | } 35 | } 36 | 37 | /* A> Now the above while loop will stop its execution, as soon as one of the array's all elements have been pushed to the new array ( i.e. sorted ). Leaving the case if the other condition of the while loop still is valid (e.g. indexB is still < b.length ). 38 | 39 | B> This will be the case for that array which will have the highest numerical value. 40 | 41 | C> So, to include that terminal case into the final sorted array, I have to check this same condition again after the while loop complete its runs. 42 | 43 | D) And concat that particular array's rest of the values sliced from that index till the end of values. 44 | */ 45 | 46 | if (indexB < b.length) { 47 | sorted = sorted.concat(b.slice(indexB)); 48 | } else { 49 | sorted = sorted.concat(a.slice(indexA)); 50 | } 51 | 52 | return sorted; 53 | 54 | } 55 | 56 | 57 | function sortFn(a, b) { 58 | return a - b; 59 | } 60 | 61 | 62 | 63 | console.log(mergeSortedArray([1, 2, 3, 5, 8], [4, 6, 7, 9])); -------------------------------------------------------------------------------- /General-JS-Problems/missing-number.js: -------------------------------------------------------------------------------- 1 | /* Question: from a unsorted array of numbers 1 to 100 excluding one number, how will you find that number. 2 | 3 | Explanation: You have an array of numbers 1 to 100 in an array. Only one number is missing in the array. The array is unsorted. Find the missing number. */ 4 | 5 | /* sum of a linear series of n numbers = n*(n+1)/2 */ 6 | 7 | function missingNumber(arr) { 8 | let sum = 0; 9 | let n = arr.length + 1; // Am adding 1, because in the given array one number is supposed to be missimg 10 | let expectedSum = (n * (n + 1)/2); 11 | 12 | for ( let i = 0; i < arr.length; i++) { 13 | sum += arr[i]; 14 | } 15 | return expectedSum -sum ; 16 | } 17 | 18 | console.log( missingNumber([5, 2, 6, 1, 3])); -------------------------------------------------------------------------------- /General-JS-Problems/multi-diamensional-array.js: -------------------------------------------------------------------------------- 1 | // Problem Statement - The first dimension represents the activity and the second one shows the number of hours spent per day for each. 2 | // calculates the percentage of the hours spent for each activity and append the percentage to the inner array. 3 | 4 | var activities = [ 5 | ['Work', 9], 6 | ['Eat', 2], 7 | ['Commute', 2], 8 | ['Play Game', 2], 9 | ['Sleep', 7] 10 | ]; 11 | 12 | for (let i = 0; i < activities.length; i++) { 13 | let percentage = ((activities[i][1] / 24) * 100).toFixed(); 14 | activities[i][2] = percentage + "%"; 15 | } 16 | 17 | console.log(activities); -------------------------------------------------------------------------------- /General-JS-Problems/narcissistic _number.js: -------------------------------------------------------------------------------- 1 | // Problem STATEMENT - Check if a given number narcissistic number 2 | /* Narcissistic number 3 | Given N, check whether it is a Narcissistic number or not. 4 | 5 | Note:Narcissistic Number is a number that is the sum of its own digits each raised to the power of the number of digits 6 | 7 | https://www.geeksforgeeks.org/narcissistic-number/ 8 | 9 | */ 10 | 11 | isNarcissistic = num => { 12 | 13 | //convert the original number to string. I can do this in the below way, or using toString() 14 | // let numStr = '' + num; 15 | 16 | let numStr = num.toString(); 17 | 18 | let numLen = numStr.length; 19 | 20 | let narcissisticResult = 0 21 | 22 | for (let i in numStr ) { 23 | narcissisticResult += Math.pow( parseInt(numStr[i]), numLen); 24 | } 25 | 26 | return num === narcissisticResult; 27 | } 28 | 29 | // console.log(isNarcissistic(153)); 30 | 31 | // 153 is Nacrissistic number - (3 digits), you can see 153 = 1^3 + 5^3 + 3^3 32 | 33 | // Alternate Solution 34 | isNarcissistic1 = num => { 35 | return num === (num.toString().split('').reduce((narcissisticResult, currentNum) => { 36 | return narcissisticResult + Math.pow(parseInt(currentNum), num.toString().length) 37 | }, 0)) 38 | } 39 | 40 | console.log(isNarcissistic1(153)); -------------------------------------------------------------------------------- /General-JS-Problems/nested-arrays-1.js: -------------------------------------------------------------------------------- 1 | // Problem-1 - Given the below nested arrays, how would we get the letter 'e'? 2 | 3 | const letters = ['a', ['b', ['c', ['d', ['e']], 'f']]]; 4 | 5 | // First, looking at the array, I can see the array ['e'] is at the 4-th level of nested arrays. 6 | // First, we'd need the second element in letters, letters[1]: 7 | console.log(letters[1]); // => [ 'b', [ 'c', [ 'd', [Array] ], 'f' ] ] 8 | 9 | 10 | // Then the second element of that resultant element 11 | console.log(letters[1][1]); // => [ 'c', [ 'd', [ 'e' ] ], 'f' ] 12 | 13 | // Going in this way I need to accessthe second element succesively of 2 more levels of nested arrays. 14 | 15 | console.log(letters[1][1][1][1]); // => [ 'e' ] 16 | 17 | 18 | -------------------------------------------------------------------------------- /General-JS-Problems/nested-arrays-function-chaining2.js: -------------------------------------------------------------------------------- 1 | // Problem statement - return only cities with population of more than 500000. And the returned city names should be sorted by their population number from lowest to hieghest 2 | // Hint - use function chaining 3 | 4 | var data = [ 5 | {"city":"seattle", "state":"WA", "population":652405, "land_area":83.9}, 6 | {"city":"new york", "state":"NY", "population":8405837, "land_area":302.6}, 7 | {"city":"boston", "state":"MA", "population":645966, "land_area":48.3}, 8 | {"city":"kansas city", "state":"MO", "population":467007, "land_area":315} 9 | ]; 10 | 11 | let bigCities = data.filter((item) => item.population > 500000) 12 | .sort((a, b) => a - b) 13 | .map((item) => item.city) 14 | 15 | console.log(bigCities); -------------------------------------------------------------------------------- /General-JS-Problems/non-repeating-char-in-a-string.js: -------------------------------------------------------------------------------- 1 | /*Find the first non repeating char in a string?*/ 2 | 3 | /*Solution - for each item in the array traverse all the other items of the array. So the */ 4 | 5 | function findFirstNonRepeatedChar(str) { 6 | 7 | let charCounter = 0; 8 | let resultChar = ''; 9 | 10 | str = str.split(''); 11 | 12 | for (let i = 0; i < str.length; i++) { 13 | charCounter = 0; 14 | 15 | for (let j = 0; j < str.length; j++) { 16 | if (str[i] === str[j]) { 17 | charCounter += 1; 18 | } 19 | } 20 | 21 | if (charCounter < 2) { 22 | resultChar = str[i]; 23 | break; 24 | } 25 | } 26 | return resultChar; 27 | } 28 | 29 | console.log(findFirstNonRepeatedChar("aaabbcdd")); -------------------------------------------------------------------------------- /General-JS-Problems/pangram.js: -------------------------------------------------------------------------------- 1 | /*Pangrams are sentences constructed by using every letter of the alphabet at least once. Construct a function to check if a string is a Panagram. 2 | 3 | Input Format: Input consists of a string ss. 4 | Length of ss can be at most 103103 (1≤|s|≤103)(1≤|s|≤103) and it may contain spaces, 5 | lower case and upper case letters. Lower-case and upper-case instances of a letter are considered the same. 6 | 7 | Output: Output a line containing pangram if ss is a pangram, otherwise output not pangram. 8 | */ 9 | 10 | /*Solutio Algo - 11 | 12 | A) Build a hash-map where each alphabets (A to Z i.e. from charCode 65 to charCode 90) are key and their value is set to false. 13 | 14 | B> Then from the given sting in the argument, push each of its alphabets to the Hash as the key and set its value to true. If the given string is a panagram, then after this operation the Hash should have all its key's value to be set to true. 15 | 16 | C> Then iterate throught the Hash's key, and if I find any key's value to be false, then return false. 17 | 18 | */ 19 | 20 | isPangram = (str) => { 21 | 22 | let alphabets = {}; 23 | 24 | str = str.replace(/ /g, '').toLowerCase(); 25 | 26 | 27 | for (let i = 65; i <= 90; i++ ) { 28 | 29 | alphabets[String.fromCharCode(i)] = false; 30 | } 31 | 32 | if (str.length < 26) { 33 | return false 34 | } else { 35 | for (let j = 0; j < str.length; j++) { 36 | alphabets[str[j]] = true; 37 | } 38 | } 39 | 40 | return true; 41 | } 42 | 43 | console.log(isPangram("The quick brown fox jumps over the lazy dog")); // should return true -------------------------------------------------------------------------------- /General-JS-Problems/permutation_array_of_numbers-Heap-Algo.js: -------------------------------------------------------------------------------- 1 | // Implementation of the pseudo-code from - https://en.wikipedia.org/wiki/Heap's_algorithm 2 | 3 | let swap = function (array, index1, index2) { 4 | let temp = array[index1]; 5 | array[index1] = array[index2]; 6 | array[index2] = temp; 7 | return array; 8 | }; 9 | 10 | function permutationHeap (array, result, n) { 11 | n = n || array.length; // set n default to array.length 12 | if ( n === 1) { 13 | result(array); // Print out the array 14 | } else { 15 | for (var i = 1; i <= n; i++ ) { 16 | permutationHeap(array, result, n-1) ; 17 | 18 | // Now with the below strategy of swapping, Heap-Algo keeps track of which elements we had already removed? Then we could just swap out unremoved elements, so that it is different in each case. 19 | if (n % 2) { 20 | swap(array, i - 1, n - 1); // when length is odd ( n % 2 is 1), select the first number, then the second number, then the third number. . . to be swapped with the last number 21 | } else { 22 | swap(array, 0, n - 1); // when length is even (n % 2 is 0), always select the first number to be swapped with the last number 23 | } 24 | } 25 | } 26 | } 27 | 28 | function output(input) { 29 | console.log(input); 30 | } 31 | 32 | permutationHeap(['a', 'b', 'c'], output); 33 | 34 | /* Time Complexity - runs in factorial time O(n!) */ 35 | 36 | /* 37 | For Explanataion on the code check my blog - https://rohan-paul.github.io/javascript/2018/04/26/Implemetning-Heap-Algorithm-to-Find-Permutation-of-set-of-Numbers/ 38 | */ 39 | -------------------------------------------------------------------------------- /General-JS-Problems/pipeFunction.js: -------------------------------------------------------------------------------- 1 | /*A pipe function takes an n sequence of functions or operations ; in which each operation takes an argument; process it; and gives the processed output as an input for the next operation in the sequence. The result of a pipe function is a function that is a bundled up version of the sequence of operations. 2 | 3 | Lets implement a pipe function to performs left-to-right function composition. 4 | 5 | Use Array.reduce() with the spread operator (...) to perform left-to-right function composition. The first (leftmost) function can accept one or more arguments; the remaining functions must be unary. 6 | */ 7 | 8 | const pipeFunction = (...funcs) => 9 | funcs.reduce((x, y) => (...args) => y(x(...args))) 10 | 11 | // Example implementation 12 | const add5 = x => x + 5 13 | const multiply = (x, y) => x * y 14 | const multiplyAndAdd5 = pipeFunction(multiply, add5) 15 | console.log(multiplyAndAdd5(5, 2)) // 15 because ((5 * 2) + 5) 16 | -------------------------------------------------------------------------------- /General-JS-Problems/print-Triangle-Staircase-1.js: -------------------------------------------------------------------------------- 1 | /*Print the following pattern 2 | Input Variable : Number of rows 3 | # 4 | # # 5 | # # # 6 | # # # # 7 | # # # # # 8 | # # # # # # 9 | # # # # # # # 10 | 11 | PROBLEM STATEMENT SPECIAL REQUIREMENT - Observe that its base and height are both equal to N ( i.e. the argument to the function, which is equal to the number of rows) 12 | 13 | */ 14 | 15 | function printTriangle(rows) { 16 | let char = '' 17 | 18 | for (let i = 1; i <= rows; i++) { 19 | for ( let j = 1; j <= i; j++) { 20 | char = char + " # "; 21 | } 22 | console.log((char)); 23 | 24 | char = ''; // Reset the char after printing 25 | } 26 | } 27 | 28 | printTriangle(7); 29 | 30 | /*Explanation 31 | A) The target is to print # on line-1 >> then print # # in line line 2 and so on. 32 | 33 | B) So when i = 1, I will print # >> when i == 2, I will print # # and so on 34 | 35 | C) So for each value of i, do another inner loop and build up the 'char' variable with i-number of # 36 | 37 | D) Then when inner loop is done, print the char variable. 38 | 39 | E) After printing, reset char, so for the next line it can print again. 40 | 41 | */ 42 | 43 | function printTriangle_alt(rows) { 44 | for (let row = 1; row <= rows; row++) { 45 | console.log("#".repeat(row)); 46 | } 47 | } 48 | 49 | // printTriangle_alt(5); -------------------------------------------------------------------------------- /General-JS-Problems/print-Triangle-Staircase-2.js: -------------------------------------------------------------------------------- 1 | /*Print the following pattern 2 | Input Variable : Number of rows 3 | # 4 | # # 5 | # # # 6 | # # # # 7 | # # # # # 8 | # # # # # # 9 | # # # # # # # 10 | */ 11 | 12 | /* Just modifying the the code for printPyramid's - by A) Not printing anything for col1 (the second for loop ) because here there's not need for "PADDING" before the * and B) making col2's max iteration value to ( 2 * row) - This second one I did just experimentally. Without it the row was printing 2 stars instead one. 13 | 14 | Observe that its base and height are both equal to number or totalRows (given as an argument to the function) 15 | */ 16 | 17 | printTriangleStaircase = totalRows => { 18 | 19 | for (let row = 0; row < totalRows; row++ ) { 20 | 21 | let line = '' 22 | 23 | for ( let col1 = 0; col1 < totalRows - row; col1++) { 24 | 25 | line = line + '' 26 | 27 | } 28 | 29 | for (let col2 = 0; col2 <= row; col2++ ) { 30 | 31 | line = line + "*" 32 | } 33 | 34 | console.log(line); 35 | } 36 | } 37 | 38 | printTriangleStaircase(5) -------------------------------------------------------------------------------- /General-JS-Problems/print-Triangle-Staircase-REVERSE-2.js: -------------------------------------------------------------------------------- 1 | /* 2 | ********* 3 | ******* 4 | ***** 5 | *** 6 | * 7 | 8 | But in my solution below, the problem statement does not contain any requirement to the no of stars to the number of rows. 9 | 10 | Same approach as reversing the Pyramid, only here, for col1, I am not adding any extra space at all, as I dont need to have the padding on the left. 11 | 12 | And for col2's max iteration value, I am just making it to (( 2 * row) - 1) - and this is out of experimentation , as without deducting the 1 , I was not getting a single start for the last row. 13 | */ 14 | 15 | printTriangleStaircaseReverse = totalRows => { 16 | 17 | for (let row = totalRows; row > 0; row-- ) { 18 | 19 | let line = '' 20 | 21 | for ( let col1 = totalRows; col1 >= row; col1--) { 22 | 23 | line = line + '' 24 | 25 | } 26 | 27 | for (let col2 = (( 2 * row) - 1); col2 > 0; col2-- ) { 28 | 29 | line = line + "*" 30 | } 31 | 32 | console.log(line); 33 | } 34 | } 35 | 36 | printTriangleStaircaseReverse(5) -------------------------------------------------------------------------------- /General-JS-Problems/print-right-aligned-triangel-staircase-problem-HR.js: -------------------------------------------------------------------------------- 1 | /* https://www.hackerrank.com/challenges/staircase/problem 2 | 3 | Consider a staircase of size n = 4 : 4 | 5 | # 6 | ## 7 | ### 8 | #### 9 | 10 | Observe that its base and height are both equal to n , and the image is drawn using # symbols and spaces. The last line is not preceded by any spaces. 11 | 12 | Write a program that prints a staircase of size . 13 | 14 | Print a staircase of size n using # symbols and spaces. 15 | 16 | Note: The last line must have 0 spaces in it. */ 17 | 18 | staircase = totalRows => { 19 | 20 | for (let row = 0; row < totalRows; row++) { 21 | 22 | let line = ''; 23 | 24 | for ( let col1 = 0; col1 < totalRows - (row + 1); col1++ ) { 25 | 26 | line += ' ' 27 | } 28 | 29 | for (let col2 = 0; col2 <= row; col2++) { 30 | line += '#' 31 | } 32 | console.log(line); 33 | } 34 | } 35 | 36 | staircase(6) 37 | 38 | // In the col1 loop, I had to do (row + 1) because, to decrease the number of empty space printed in each line, so the last line (the base of triangle) would not contain any spaces and ONLY # (which was the requirement of the original problem) -------------------------------------------------------------------------------- /General-JS-Problems/print-side-by-side-bow-shape-triangle.js: -------------------------------------------------------------------------------- 1 | /* - Print the following shape, where the maximum number of stars in the middle postition is maxNum 2 | 3 | * 4 | ** 5 | *** 6 | **** 7 | ***** 8 | ****** 9 | ******* 10 | ******** 11 | ********* 12 | ********** 13 | ********* 14 | ******** 15 | ******* 16 | ****** 17 | ***** 18 | **** 19 | *** 20 | ** 21 | * 22 | 23 | Side by triangel bow shaped 24 | */ 25 | 26 | bowShapedTriangle = maxNum => { 27 | 28 | let triangle_1 = ''; 29 | 30 | // First build the triangle upto maxNum of rows with maxNum of * 31 | for (let i = 0; i < maxNum; i++) { 32 | triangle_1 += '*' 33 | console.log(triangle_1); 34 | } 35 | 36 | // Then just reduce the trianlge starting from next line and and counting from maxNum - 1. As after the 10 '*' the next line should print 9 '*' 37 | for (let i = maxNum - 1; i >= 1 ; i-- ) { 38 | triangle_1 = triangle_1.slice(0, -1); 39 | console.log(triangle_1); 40 | } 41 | } 42 | 43 | bowShapedTriangle(10) 44 | 45 | // String.slice method - The slice() method extracts a section of a string and returns it as a new string, without modifying the original string. 46 | 47 | // str.slice(beginIndex[, endIndex]) 48 | 49 | // If the endIndes is negative, it is treated as strLength + endIndex where strLength is the length of the string (for example, if endIndex is -3 it is treated as strLength - 3). -------------------------------------------------------------------------------- /General-JS-Problems/pure-impure-func-with-slice-and-splice.js: -------------------------------------------------------------------------------- 1 | /* An Impure Function - The splice() method changes the contents of an array by removing existing elements and/or adding new elements. 2 | 3 | syntaqx >>>> array.splice(start[, deleteCount[, item1[, item2[, ...]]]]) 4 | 5 | item1, item2, ... Optional - The elements to add to the array, beginning at the start index. 6 | 7 | Return value - An array containing the deleted elements. 8 | */ 9 | 10 | let arr = [1, 2, 3, 4, 5]; 11 | 12 | console.log(arr.splice(0, 3)); //=> [1, 2, 3] 13 | 14 | console.log(arr.splice(0, 3)); //=> [4, 5] 15 | 16 | console.log(arr.splice(0, 3)); //=> [] 17 | 18 | console.log(arr); //=> [] 19 | 20 | 21 | /* A Pure Function - The slice() method returns a shallow copy of a portion of an array into a new array object selected from begin to end (end not included). 22 | 23 | 24 | 25 | 26 | */ 27 | 28 | let arr1 = [1, 2, 3, 4, 5]; 29 | 30 | console.log(arr1.slice(0, 3)); //=> [1, 2, 3] 31 | 32 | console.log(arr1.slice(0, 3)); //=> [1, 2, 3] 33 | 34 | console.log(arr1.slice(0, 3)); //=> [1, 2, 3] 35 | 36 | console.log(arr1); //=> [ 1, 2, 3, 4, 5 ] 37 | 38 | 39 | 40 | /* Slice and Splice do the same thing to the array but in a different way, slice returns a new array according to the input, guaranteeing the same output per input every time. Splice on the other hand modifies the original array and the same output per input is not guaranteed. */ 41 | 42 | // Look at this, how splice() returns the deleted elements of the array, leaving the original array mutated. 43 | let myArr1 = [ 2, 1, 3, 4] 44 | 45 | console.log(myArr1.splice(1, 1)); // => [ 1 ] 46 | 47 | console.log(myArr1); // => [ 2, 3, 4 ] -------------------------------------------------------------------------------- /General-JS-Problems/random-code-1.js: -------------------------------------------------------------------------------- 1 | n_th_fibonacci = n => { 2 | let [a, b] = [0, 1]; 3 | 4 | while (--n) { 5 | [a, b] = [b, b + a ] 6 | } 7 | return b; 8 | } 9 | 10 | console.log(n_th_fibonacci(10000)) // => 55 -------------------------------------------------------------------------------- /General-JS-Problems/remove-duplicate-from-Array-O(n).js: -------------------------------------------------------------------------------- 1 | // uniq - Takes an array of numbers, and returns the unique numbers. Can you do it in O(N) time? 2 | 3 | /* Solution Algo - 4 | 5 | Keeping track of already seen numbers in an object, because checking if an object has a certain key 6 | is cheap (it takes O(1) time). 7 | 8 | But if I didn't use this object, I'd have to check if result contains current on every turn of the 9 | loop, with something like below. 10 | 11 | < if (result.indexOf(currentElem) < 0) result.push(currentElem); > 12 | 13 | This would take up to O(N * log(N)) time. 14 | 15 | */ 16 | 17 | returnUnique = arr => { 18 | let seenObj = {} 19 | 20 | return arr.reduce((finalArr, currentElem) => { 21 | if (currentElem in seenObj) { 22 | return finalArr 23 | } else { 24 | seenObj[currentElem] = true 25 | console.log(seenObj) 26 | return finalArr.concat(currentElem) 27 | } 28 | }, []) 29 | } 30 | 31 | console.log(returnUnique([1, 4, 2, 2, 3, 4, 8])) 32 | 33 | /* In the last line, finalArr.concat(currentElem), I can NOT use finalArr.push() because of the following - (will get error - "array.push not a function" ) 34 | 35 | https://stackoverflow.com/questions/45742030/push-method-not-available-in-reduce-array-accumulator?rq=1 36 | 37 | "This is because Array.prototype.push() returns the new length of the array, not the array itself. Your code will run through one iteration of your reducer, set the accumulative value to an integer, and then fail on the next iteration." 38 | 39 | 40 | Further Reading 41 | 42 | 1. https://stackoverflow.com/a/53526999/1902852 43 | 44 | */ 45 | 46 | // ******************************************** 47 | 48 | // Another even more simpler Implementation of above with O(n) performance 49 | 50 | const getUnique = (array) => { 51 | 52 | // below variable will keep track of already seen numbers in an object, 53 | // because checking if an object has a certain key is cheap (it takes O(1) time). 54 | let objWithOnlyUniqueArrayElements = {} 55 | 56 | return array.filter((elem) => !(objWithOnlyUniqueArrayElements[elem] = elem in objWithOnlyUniqueArrayElements)) 57 | } 58 | 59 | const a1 = [5, 6, 0, 4, 9, 2, 3, 5, 0, 3, 4, 1, 5, 4, 9] 60 | console.log(getUnique(a1)) 61 | 62 | /* 63 | [ 64 | 5, 6, 0, 4, 65 | 9, 2, 3, 1 66 | ] 67 | 68 | Explanation - 69 | */ 70 | 71 | -------------------------------------------------------------------------------- /General-JS-Problems/remove-duplicate-from-string.js: -------------------------------------------------------------------------------- 1 | // Removing duplicate characters from a string. 2 | 3 | removeDupCharFromStr = (str) => { 4 | 5 | let result = []; 6 | 7 | for (let i = 0; i < str.length; i++) { 8 | if ((result.indexOf(str[i])) === -1 ) { 9 | result.push(str[i]) 10 | } 11 | } 12 | return result.join(''); 13 | } 14 | 15 | // console.log(removeDupCharFromStr("Rohaaan")); 16 | 17 | // More compact solution to remove duplicated char from str with ES6 Set 18 | removeDupWordsFromStr_1 = (str) => { 19 | return [...new Set([...str])].join(''); 20 | } 21 | 22 | console.log(removeDupWordsFromStr_1("Rohaaan")); 23 | 24 | 25 | // Remove duplicate words from string separated by a comma and a space and return the string containing only unique words - the below solution will NOT remove duplicate characters from a string, its only for words. 26 | 27 | removeDupWordsFromStrAlt = (str) => { 28 | return str.split(',').filter((item, index, array) => { 29 | return index === array.indexOf(item); 30 | }).join(','); 31 | } 32 | 33 | // console.log(removeDupWordsFromStrAlt("spanner, span, spaniel, span")); // => spanner, span, spaniel 34 | // console.log(removeDupWordsFromStrAlt("Rohaaaaan")); // => Rohaaaaan 35 | 36 | // remove duplicates from string with the new Set method of ES6 37 | 38 | removeDupWordsFromStr = (str) => { 39 | return Array.from(new Set(str.split(','))).toString(); 40 | } 41 | 42 | // console.log(removeDupWordsFromStr("spanner, span, spaniel, span")); -------------------------------------------------------------------------------- /General-JS-Problems/repeatedly-add-digits-till-sum-is-single.js: -------------------------------------------------------------------------------- 1 | // Given a non-negative number, repeatedly add all its digits until the result has only one digit. 2 | 3 | addDigits3 = num => { 4 | 5 | num += '' // This is just converting the number to string, should be equivalent to num.toString() 6 | 7 | while (num.length !==1 ) { 8 | 9 | let sum = 0; 10 | 11 | for (let i = 0; i < num.length; i++) { 12 | sum += parseInt(num[i]); 13 | } 14 | 15 | // Now once the first sum is calculate for the first set of digits, now reset the original num to be equal to sum. So for the next while loop, that number's digits can be summed up 16 | 17 | num = '' + sum; 18 | } 19 | return parseInt(num); 20 | } 21 | 22 | console.log(addDigits3(38)); // => 2 -------------------------------------------------------------------------------- /General-JS-Problems/reverseArray-of-numbers.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | // reversing an array using a temporary var 4 | var reverseArray = function (arr) { 5 | var reverse = []; 6 | for (i = arr.length; i >= 0; i--) { 7 | reverse.push(arr[i]) 8 | } 9 | return reverse; 10 | }; 11 | 12 | // reversing an array without using a temporary var 13 | /* In below, the map() method creates a new array with the results of calling a provided function on every element in the calling array. 14 | 15 | A> So, in the callback function, I am just pulling the last element of the given original array, and returning it first. As for the last element the part arr.[arr.length - 1 - index] is arr.[arr.length - 1 - 0] - which is the last element of the array. 16 | 17 | (and the argument index is the index of the current element being processed, ie. it will start form index=0 of the given original array). 18 | 19 | B> Then for the second loop, index will be 1, i.e. I am pulling the element (arr.length - 1 - 1) i.e. the second last element, and returning it to be placed as the second element of the new array to be created. 20 | 21 | C> And this way, for the last loop, I will be pulling arr[(arr.((length -1)-(length-1)))] element, i.e. the arr[0] element of the original array, and place it to be the last 22 | */ 23 | var reverseArray = function(arr) { 24 | return arr.map(function(item, index) { 25 | return arr[arr.length-1-index]; 26 | }); 27 | }; 28 | // ES6 version 29 | function reverseArray (arr) { 30 | return arr.map((item, index) => arr[arr.length-1-index]); 31 | } 32 | 33 | // Another alternative to reverse an array without using temp variable. While does not require a temp variable, but runs at O(n^2) time. 34 | // Use splice to replace consecutive elements of the array, starting from index=0 with the last element of the array. So in each loop I pop() the last element of the array and take that element to replace the i-th element of the array starting from left-most begining. 35 | function inPlaceReverse(arr) { 36 | var i = 0; 37 | while (i < arr.length - 1 ) { 38 | arr.splice(i, 0, arr.pop()); 39 | i++; 40 | } 41 | return arr; 42 | } 43 | console.log(inPlaceReverse([2, 3, 4])); -------------------------------------------------------------------------------- /General-JS-Problems/search-string-heighlight.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 |
10 |