Skip to content

Commit 7372537

Browse files
Add comprehensive guides for loops and strings
Introduced new documentation and example files for JavaScript loops and strings, including 'loops/loops.md', 'loops/loops.js', 'string/string.md', 'string/string.js', and 'string/regex.md'. Updated 'index.md' to include these new sections. Enhanced 'Arrays/array.md' with mutating/non-mutating method comparison table and additional details.
1 parent efd320c commit 7372537

File tree

7 files changed

+1147
-0
lines changed

7 files changed

+1147
-0
lines changed

Arrays/array.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,15 @@ JavaScript array methods can be categorized into two groups:
2626
original one.
2727

2828
There are 9 methods in total that mutate the arrays,
29+
30+
1. `push`: Adds one or more elements to array.
2931
```javascript
3032
let arr1 = [1, 2, 3];
3133
// Syntax: array.push(element1, element2, ..., elementN)
3234
let newLength1 = arr1.push(4, 5); // arr1 is now [1, 2, 3, 4, 5], newLength1 is 5
3335
```
3436
the end of the array and returns the new length.
37+
3538
2. `pop`: Removes the last element from the
3639
array and returns that element.
3740
```javascript
@@ -183,6 +186,18 @@ let arrR = ['1', '2', '3', '4', '5'];
183186
let rightReduced = arrR.reduceRight((acc, curr) => acc + curr); // "54321"
184187
```
185188

189+
| Mutating method | Non-mutating alternative
190+
| copyWithin() |No one-method alternative
191+
fill() No one-method alternative
192+
pop() slice(0, -1)
193+
push(v1, v2) concat([v1, v2])
194+
reverse() toReversed()
195+
shift() slice(1)
196+
sort() toSorted()
197+
splice() toSpliced()
198+
unshift(v1, v2) toSpliced(0, 0, v1, v2)
199+
200+
186201
### Static Methods
187202

188203
1. `Array.from`: Creates a new, shallow-copied Array instance from an iterable or array-like object.

index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33

44
## 📚 Table of Contents
5+
- [loops](loops/loops.md)
6+
- [String](string/string.md)
57
- [Arrays](Arrays/array.md)
8+
- [JavaScript Regular Expression](string/regex.md)
69
- [Functions](functions/functions.md)
710
- [Closures](Closures/closures.md)
811
- [Event Loop](JS-Interview-Questions/eventloop.md)

loops/loops.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
const Cars = ["BMW", "Mercedes", "Toyota", "Honda"];
3+
4+
for (let i = 0; i < Cars.length; i++) {
5+
console.log(Cars[i]);
6+
}
7+
8+
while (Cars.length > 0) {
9+
console.log(Cars.shift());
10+
}

loops/loops.md

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
# JavaScript Loops: A Complete Guide
2+
3+
## 1. Why Loops?
4+
Loops let you repeat an action multiple times without duplicating code. They are essential for:
5+
- Iterating over arrays, objects, strings
6+
- Processing data (filtering, transforming, aggregating)
7+
- Running asynchronous tasks sequentially
8+
9+
---
10+
## 2. Core Loop Types
11+
### 2.1 `for` Loop (Classic Index Loop)
12+
Best when you need the index or want fine-grained control.
13+
```js
14+
const cars = ["BMW", "Mercedes", "Toyota", "Honda"];
15+
for (let i = 0; i < cars.length; i++) {
16+
console.log(i, cars[i]);
17+
}
18+
```
19+
Key points:
20+
- Initialization (`let i = 0`), condition (`i < cars.length`), update (`i++`)
21+
- Can `break` or `continue`
22+
- Good for performance-sensitive code
23+
24+
### 2.2 `while` Loop
25+
Runs while the condition is true.
26+
```js
27+
let count = 3;
28+
while (count > 0) {
29+
console.log("Count:", count);
30+
count--;
31+
}
32+
```
33+
Use when the number of iterations isn’t known ahead of time.
34+
35+
### 2.3 `do...while` Loop
36+
Executes **at least once** before checking the condition.
37+
```js
38+
let n = 0;
39+
do {
40+
console.log("Executed once even if condition is false initially");
41+
} while (n > 0);
42+
```
43+
44+
### 2.4 `for...of` (Iterable Loop)
45+
Great for arrays, strings, Maps, Sets.
46+
```js
47+
const langs = ["JS", "Python", "Go"];
48+
for (const lang of langs) {
49+
console.log(lang);
50+
}
51+
```
52+
Benefits:
53+
- Cleaner than index loops
54+
- Works with any iterable (implements `[Symbol.iterator]`)
55+
56+
### 2.5 `for...in` (Object Property Enumeration)
57+
Iterates over **enumerable keys** (including inherited ones).
58+
```js
59+
const user = { name: "Aditya", age: 23 };
60+
for (const key in user) {
61+
console.log(key, user[key]);
62+
}
63+
```
64+
Avoid using `for...in` on arrays (order isn’t guaranteed). Combine with `hasOwnProperty` if needed:
65+
```js
66+
for (const key in user) {
67+
if (Object.prototype.hasOwnProperty.call(user, key)) {
68+
console.log(key, user[key]);
69+
}
70+
}
71+
```
72+
73+
### 2.6 `Array.prototype.forEach`
74+
Higher-order method for arrays.
75+
```js
76+
const nums = [1, 2, 3];
77+
nums.forEach((value, index) => console.log(index, value));
78+
```
79+
Limitations:
80+
- Can’t use `break` / `continue`
81+
- Doesn’t return a new array (use `map` if transforming)
82+
83+
### 2.7 `for await...of` (Async Iteration)
84+
Used with async iterables or arrays of promises.
85+
```js
86+
const urls = [
87+
fetch('https://jsonplaceholder.typicode.com/todos/1'),
88+
fetch('https://jsonplaceholder.typicode.com/todos/2')
89+
];
90+
91+
(async () => {
92+
for await (const res of urls) {
93+
const data = await res.json();
94+
console.log(data.id);
95+
}
96+
})();
97+
```
98+
99+
---
100+
## 3. Comparing Loop Types
101+
| Loop | Use Case | Supports break/continue | Best For |
102+
|---------------|----------|--------------------------|----------|
103+
| for | Indexed control | Yes | Arrays with index needs |
104+
| while | Unknown end condition | Yes | Event polling, dynamic termination |
105+
| do...while | Run at least once | Yes | Menu/input loops |
106+
| for...of | Iterables | Yes | Arrays, strings, Sets, Maps |
107+
| for...in | Enumerating object keys | Yes | Plain objects (with hasOwnProperty) |
108+
| forEach | Array iteration with side-effects | No | Simple per-item processing |
109+
| for await...of| Async iterables/promises | Yes | Sequential async handling |
110+
111+
---
112+
## 4. Loop Control: `break`, `continue`, and Labels
113+
```js
114+
for (let i = 0; i < 5; i++) {
115+
if (i === 2) continue; // Skip 2
116+
if (i === 4) break; // Stop loop
117+
console.log(i);
118+
}
119+
```
120+
### Labeled Break (Avoid unless necessary)
121+
```js
122+
outer: for (let i = 0; i < 3; i++) {
123+
for (let j = 0; j < 3; j++) {
124+
if (i === 1 && j === 1) break outer;
125+
console.log(i, j);
126+
}
127+
}
128+
```
129+
130+
---
131+
## 5. Iterating Objects Safely
132+
```js
133+
const person = { first: 'Ada', last: 'Lovelace' };
134+
Object.keys(person).forEach(k => console.log(k, person[k]));
135+
Object.entries(person).forEach(([k, v]) => console.log(k, v));
136+
```
137+
Prefer `Object.keys/values/entries` over `for...in` when you want only own properties.
138+
139+
---
140+
## 6. Avoid Mutating While Iterating
141+
Bad pattern:
142+
```js
143+
const arr = [1,2,3,4];
144+
for (let i = 0; i < arr.length; i++) {
145+
if (arr[i] % 2 === 0) arr.splice(i, 1); // Skips elements
146+
}
147+
```
148+
Better:
149+
```js
150+
const filtered = arr.filter(x => x % 2 !== 0);
151+
```
152+
Or iterate from end:
153+
```js
154+
for (let i = arr.length - 1; i >= 0; i--) {
155+
if (arr[i] % 2 === 0) arr.splice(i, 1);
156+
}
157+
```
158+
159+
---
160+
## 7. Building Transformations Manually
161+
```js
162+
const numbers = [1,2,3,4];
163+
// map alternative
164+
const doubled = [];
165+
for (let i = 0; i < numbers.length; i++) {
166+
doubled.push(numbers[i] * 2);
167+
}
168+
// filter alternative
169+
const evens = [];
170+
for (const n of numbers) {
171+
if (n % 2 === 0) evens.push(n);
172+
}
173+
// reduce alternative (sum)
174+
let sum = 0;
175+
for (const n of numbers) sum += n;
176+
```
177+
178+
---
179+
## 8. Performance Notes
180+
- `for` with cached length is slightly faster in tight loops:
181+
```js
182+
for (let i = 0, len = arr.length; i < len; i++) {}
183+
```
184+
- Avoid heavy synchronous loops in the UI thread (they block rendering)
185+
- For large data, consider batching with `setTimeout` / `requestIdleCallback`
186+
187+
---
188+
## 9. Async Pitfalls in Loops
189+
### Using `var` inside loops with async callbacks
190+
```js
191+
for (var i = 1; i <= 3; i++) {
192+
setTimeout(() => console.log(i), 0); // 4,4,4
193+
}
194+
```
195+
Fix with `let` (block scoping) or IIFE:
196+
```js
197+
for (let i = 1; i <= 3; i++) {
198+
setTimeout(() => console.log(i), 0); // 1,2,3
199+
}
200+
```
201+
Sequential async with `for...of`:
202+
```js
203+
async function process(ids) {
204+
for (const id of ids) {
205+
await doAsync(id); // waits each turn
206+
}
207+
}
208+
```
209+
Parallel async:
210+
```js
211+
await Promise.all(ids.map(doAsync));
212+
```
213+
214+
---
215+
## 10. When to Use What
216+
| Need | Pick |
217+
|------|------|
218+
| Index + control | for |
219+
| Unknown iteration count | while |
220+
| Run at least once | do...while |
221+
| Clean element iteration | for...of |
222+
| Own object keys | Object.keys + forEach |
223+
| Transform / filter / accumulate | map / filter / reduce |
224+
| Async sequential | for await...of or for...of with await |
225+
| Async parallel | Promise.all |
226+
227+
---
228+
## 11. Practical Examples
229+
### Summing Nested Arrays
230+
```js
231+
const matrix = [[1,2],[3,4],[5,6]];
232+
let total = 0;
233+
for (const row of matrix) {
234+
for (const value of row) total += value;
235+
}
236+
console.log(total); // 21
237+
```
238+
### Counting Frequencies
239+
```js
240+
const letters = ['a','b','a','c','b','a'];
241+
const freq = {};
242+
for (const ch of letters) {
243+
freq[ch] = (freq[ch] || 0) + 1;
244+
}
245+
console.log(freq); // { a:3, b:2, c:1 }
246+
```
247+
### Flatten One Level
248+
```js
249+
const nested = [1,[2,3],[4,5]];
250+
const flat = [];
251+
for (const item of nested) {
252+
if (Array.isArray(item)) {
253+
for (const inner of item) flat.push(inner);
254+
} else flat.push(item);
255+
}
256+
console.log(flat); // [1,2,3,4,5]
257+
```
258+
259+
---
260+
## 12. Edge Cases
261+
- Mutating `length` during a loop affects iteration.
262+
- `forEach` skips holes in sparse arrays; `for` does not if index exists.
263+
- `for...in` order is not guaranteed for integer-like keys.
264+
- `break` in `try/finally` still executes `finally`.
265+
266+
---
267+
## 13. Mini Cheatsheet
268+
| Goal | Preferred | Alternate |
269+
|------|-----------|-----------|
270+
| Iterate array values | for...of | for / forEach |
271+
| Need index + value | for | arr.entries() + for...of |
272+
| Iterate string chars | for...of | classic for |
273+
| Object own keys | Object.keys(obj) | for...in + hasOwnProperty |
274+
| Parallel async tasks | Promise.all | forEach + async (avoid) |
275+
| Sequential async tasks | for...of + await | reduce chain |
276+
277+
---
278+
## 14. Practice Exercises
279+
1. Reverse an array in-place using a `for` loop.
280+
2. Write a loop to find the second largest number.
281+
3. Use `for...of` to sum only even numbers in an array.
282+
4. Implement a manual version of `Array.prototype.filter` using a loop.
283+
5. Loop through a string and count vowels.
284+
285+
---
286+
## 15. Summary
287+
Mastering loops means knowing not just the syntax, but **which tool fits which scenario**. Start with readable constructs (`for...of`, array methods) and drop to lower-level loops (`for`, `while`) when you need control or performance.
288+
289+
Happy looping!

0 commit comments

Comments
 (0)