Javascript Recursion for Beginners (super simple)
JS
S
JavaScriptSuper simple explanation of how recursive functions work in JS. So basically what we are doing with a recursive function call is: Trivia: Reduce the list at each step until we get to an empty list; Trivia: Reduce the number at each step until we get to 0; Trivia: Reduce the string at each step until we get to ''; Computation: On the way return the value what you want to add, append, subtract, multiply with the result
1/*
2 offuscateString('test');
3 offuscateString('shoes');
4 offuscateString('shoes');
5 offuscateString('shoes');
6 offuscateString('shoes');
7 // result = test shoes shoes shoes shoes
8*/
9let counter = 5;
10const offuscateStringDummy = (sourceStr) => {
11 if (counter === 0) {
12 return '';
13 }
14 counter--;
15 return sourceStr + ' ' + offuscateStringDummy('shoes');
16}
17
18const off = offuscateStringDummy('test');
19console.log(off)
20
21
22// ==============================================================================================================================
23/* Second Example
24 Ok, now we are running this order:
25 offuscateStringLessDummy('test');
26 // YUP WE ARE CALLING SHOES WITHOUT THE LAST CHAR, COUNTER === 4
27 offuscateStringLessDummy('shoe');
28 offuscateStringLessDummy('sho');
29 offuscateStringLessDummy('sh');
30 offuscateStringLessDummy('s');
31*/
32let counter = 5;
33const offuscateStringLessDummy = (sourceStr) => {
34 if (counter === 0) {
35 return '';
36 }
37 counter--;
38 return sourceStr + ' ' + offuscateStringLessDummy('shoes'.slice(0, counter));
39}
40
41const off = offuscateStringLessDummy('test');
42console.log(off)
43
44// ==============================================================================================================================
45/*
46 Smart
47 Now we are removing last char of the str on every call and using the incrementally smaller string as our counter, like so:
48 offuscateStringSmart('test')
49 offuscateStringSmart('tes')
50 offuscateStringSmart('te')
51 offuscateStringSmart('t')
52
53 result: test tes te t
54
55*/
56const offuscateStringSmart = (sourceStr) => {
57 if (sourceStr.length === 0) {
58 return '';
59 }
60 return sourceStr + ' ' + offuscateStringSmart(sourceStr.slice(0, sourceStr.length - 1));
61}
62
63const off = offuscateStringSmart('test');
64console.log(off)
65
66
67// ==============================================================================================================================
68/*
69 OK, now that the basics are covered:
70 WE WILL REVERT THE STRING, BY CUTTING IT DOWN FROM THE END ON EACH ITERATION
71 AND GLUING THE LAST CHARACTER
72 offuscateStringSmarter('t')
73 offuscateStringSmarter('s')
74 offuscateStringSmarter('e')
75 offuscateStringSmarter('t')
76
77 REMEMBER THE PROCESSING (BOTTOM OF STACK UP, SO THE LAST ITEM ON THE CALL STACK IS "offuscateStringSmarter('t)")
78 RECURSION STOPS THERE AS WILL HIT 0
79 't' + 's' + 'e' + 't'
80
81 // result tset
82*/
83const offuscateStringSmarter = (sourceStr) => {
84 console.log('>', sourceStr)
85 if (sourceStr.length === 0) {
86 return '';
87 }
88 const lastChar = sourceStr.charAt(sourceStr.length - 1);
89 const withouLastChar = sourceStr.slice(0, sourceStr.length - 1);
90 return lastChar + offuscateStringSmarter(withouLastChar);
91}
92
93const off = offuscateStringSmarter('test');
94console.log('result', off)
95
96
97// ==============================================================================================================================
98/*
99 OK, To finalize, lets step it up a bit, like so:
100 SEQUENCE OF CALLS
101 offuscateStringGenius('test')
102 offuscateStringGenius('tes')
103 offuscateStringGenius('te')
104 offuscateStringGenius('t')
105
106 BUILD UP RESULT (DONT FORGET THAT WE ARE RETURNING THE lastCharHashed + '')
107 '' HUN?
108 YES, DO NOT FORGET THAT '' CAME FROM OUR STOP CONDITION
109 offuscateStringGenius('t') 74 ['t']
110 offuscateStringGenius('te') 65 ['e']
111 offuscateStringGenius('tes') 73 ['s']
112 offuscateStringGenius('test') 74 ['t']
113*/
114const offuscateStringGenius = (sourceStr) => {
115 console.log('>', sourceStr)
116 if (sourceStr.length === 0) {
117 return '';
118 }
119 const lastChar = sourceStr.charAt(sourceStr.length - 1);
120 const withouLastChar = sourceStr.slice(0, sourceStr.length - 1);
121 const lastCharHashed = lastChar.charCodeAt(0).toString(16)
122 return lastCharHashed + offuscateStringGenius(withouLastChar);
123}
124
125const off = offuscateStringGenius('test');
126console.log('result', off) //74736574
127
128// IF YOU THING A BIT ON OUR CASE, IT'S KIND OF A REDUCTION, WE HAVE REDUCED THE STRING FROM 5 CHARACTERS TO AN EMPTY STRING
129
130// ==============================================================================================================================
131// More simple examples
132/*
133 multiplyWithRecursion(2,4) // 2
134 multiplyWithRecursion(2,3) // 2
135 multiplyWithRecursion(2,2) // 2
136 multiplyWithRecursion(2,1) // 2
137 // Unwind
138 2 + 2 + 2 + 2 + 0
139*/
140const multiplyWithRecursion = (x,y) => {
141 // Stop condition
142 if(y === 0){
143 return 0;
144 }
145 y--;
146 return x + multiplyWithRecursion(x, y);
147}
148const res = multiplyWithRecursion(2,4);
149console.log('res', res);
150
151
152
153/* Recursion on Lists
154Trivia: Reduce the list at each step until we get to an empty list;
155Remember: We are adding all sumAllNumbersInTheList() return values, like so:
156 sumAllNumbersInTheList([1,2,3,4,5]); // 1
157 sumAllNumbersInTheList([2,3,4,5]); // 2
158 sumAllNumbersInTheList([3,4,5]); // 3
159 sumAllNumbersInTheList([4,5]); // 4
160 sumAllNumbersInTheList([5]); //5
161 sumAllNumbersInTheList([]); //0
162
163 UNWIND:
164 1+2+3+4+5+0 = 15
165 sumAllNumbersInTheList([1,2,3,4,5])
166 1 + sumAllNumbersInTheList([2,3,4,5])
167 1 + 2 + sumAllNumbersInTheList([3,4,5])
168 1 + 2 + 3 + sumAllNumbersInTheList([4,5])
169 1 + 2 + 3 + 4 sumAllNumbersInTheList([5])
170 1 + 2 + 3 + 4 + 5 sumAllNumbersInTheList([])
171 1 + 2 + 3 + 4 + 5 + 0
172*/
173const sumAllNumbersInTheList = (list) => {
174 if(list.length === 0) {
175 return 0; // we are suming, remember?
176 } else {
177 return list.shift() + sumAllNumbersInTheList(list); // remember: shift() reduces the array by 1
178 }
179};
180
181const res = sumAllNumbersInTheList([1,2,3,4,5]);
182console.log('res', res); // 15
183
184
185// ==============================================================================================================================
186/*
187 removeSpecificElement(x, [1,2,3,4,5]) // [1]
188 removeSpecificElement(x, [2,3,4,5]) // [2]
189 removeSpecificElement(x, [3,4,5]) // [3]
190 removeSpecificElement(x, [4,5]) // [5]
191
192 UNWIND
193 concat
194 [1][2][3][5]
195*/
196
197const removeSpecificElement = (itemToRemove, list) => {
198 console.log('process', itemToRemove, list)
199 const indexOfItemToRemove = list.indexOf(itemToRemove);
200 if(indexOfItemToRemove === 0) {
201 // Finally the item to remove is on position zero, exit the recursion
202 list.shift();
203 return list;
204 } else {
205 // reduce the list but keep element
206 const shiftedEl = list.shift();
207 return [shiftedEl].concat(removeSpecificElement(itemToRemove, list));
208 }
209};
210
211const res1 = removeSpecificElement(4, [1,2,3,4,5]);
212console.log(res1);Created on 2/19/2019