Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions src/03-array/11-array-chunking.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// src/03-array/11-array-chunking.js

/**
* Array Chunking - Split an array into chunks of a specified size
* Common use case: Pagination, batch processing, data visualization
*/

// Approach 1: Using slice method
function chunkArray(array, chunkSize) {
if (chunkSize <= 0) {
throw new Error('Chunk size must be greater than 0');
}

const result = [];
for (let i = 0; i < array.length; i += chunkSize) {
result.push(array.slice(i, i + chunkSize));
}
return result;
}

// Approach 2: Using splice method (modifies original array)
function chunkArraySplice(array, chunkSize) {
if (chunkSize <= 0) {
throw new Error('Chunk size must be greater than 0');
}

const result = [];
const arrayCopy = [...array]; // Create a copy to avoid modifying original

while (arrayCopy.length > 0) {
result.push(arrayCopy.splice(0, chunkSize));
}
return result;
}

// Approach 3: Using reduce method (functional approach)
function chunkArrayReduce(array, chunkSize) {
if (chunkSize <= 0) {
throw new Error('Chunk size must be greater than 0');
}

return array.reduce((chunks, item, index) => {
const chunkIndex = Math.floor(index / chunkSize);

if (!chunks[chunkIndex]) {
chunks[chunkIndex] = []; // Start a new chunk
}

chunks[chunkIndex].push(item);
return chunks;
}, []);
}

// Examples
console.log('=== Array Chunking Examples ===\n');

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log('Original array:', numbers);

console.log('\nChunk size 3 (slice method):', chunkArray(numbers, 3));
// Output: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

console.log('Chunk size 4 (splice method):', chunkArraySplice(numbers, 4));
// Output: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]

console.log('Chunk size 2 (reduce method):', chunkArrayReduce(numbers, 2));
// Output: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

// Real-world example: Paginating data
const users = [
'Alice', 'Bob', 'Charlie', 'David', 'Eve',
'Frank', 'Grace', 'Henry', 'Ivy', 'Jack'
];

const itemsPerPage = 3;
const pages = chunkArray(users, itemsPerPage);

console.log('\n=== Pagination Example ===');
console.log(`Total users: ${users.length}`);
console.log(`Items per page: ${itemsPerPage}`);
console.log(`Total pages: ${pages.length}\n`);

pages.forEach((page, index) => {
console.log(`Page ${index + 1}:`, page);
});

// Edge cases
console.log('\n=== Edge Cases ===');
console.log('Empty array:', chunkArray([], 3));
console.log('Chunk size larger than array:', chunkArray([1, 2], 5));
console.log('Chunk size of 1:', chunkArray([1, 2, 3], 1));

// to see the output of this file use the command: node src/03-array/11-array-chunking.js
93 changes: 93 additions & 0 deletions src/03-array/11-array-chunking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// src/03-array/11-array-chunking.ts

/**
* Array Chunking - Split an array into chunks of a specified size
* Common use case: Pagination, batch processing, data visualization
*/

// Approach 1: Using slice method
function chunkArray<T>(array: T[], chunkSize: number): T[][] {
if (chunkSize <= 0) {
throw new Error('Chunk size must be greater than 0');
}

const result: T[][] = [];
for (let i = 0; i < array.length; i += chunkSize) {
result.push(array.slice(i, i + chunkSize));
}
return result;
}

// Approach 2: Using splice method (modifies original array)
function chunkArraySplice<T>(array: T[], chunkSize: number): T[][] {
if (chunkSize <= 0) {
throw new Error('Chunk size must be greater than 0');
}

const result: T[][] = [];
const arrayCopy = [...array]; // Create a copy to avoid modifying original

while (arrayCopy.length > 0) {
result.push(arrayCopy.splice(0, chunkSize));
}
return result;
}

// Approach 3: Using reduce method (functional approach)
function chunkArrayReduce<T>(array: T[], chunkSize: number): T[][] {
if (chunkSize <= 0) {
throw new Error('Chunk size must be greater than 0');
}

return array.reduce((chunks: T[][], item: T, index: number) => {
const chunkIndex = Math.floor(index / chunkSize);

if (!chunks[chunkIndex]) {
chunks[chunkIndex] = []; // Start a new chunk
}

chunks[chunkIndex].push(item);
return chunks;
}, []);
}

// Examples
console.log('=== Array Chunking Examples ===\n');

const numbers: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log('Original array:', numbers);

console.log('\nChunk size 3 (slice method):', chunkArray(numbers, 3));
// Output: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

console.log('Chunk size 4 (splice method):', chunkArraySplice(numbers, 4));
// Output: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]

console.log('Chunk size 2 (reduce method):', chunkArrayReduce(numbers, 2));
// Output: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

// Real-world example: Paginating data
const users: string[] = [
'Alice', 'Bob', 'Charlie', 'David', 'Eve',
'Frank', 'Grace', 'Henry', 'Ivy', 'Jack'
];

const itemsPerPage = 3;
const pages = chunkArray(users, itemsPerPage);

console.log('\n=== Pagination Example ===');
console.log(`Total users: ${users.length}`);
console.log(`Items per page: ${itemsPerPage}`);
console.log(`Total pages: ${pages.length}\n`);

pages.forEach((page, index) => {
console.log(`Page ${index + 1}:`, page);
});

// Edge cases
console.log('\n=== Edge Cases ===');
console.log('Empty array:', chunkArray([], 3));
console.log('Chunk size larger than array:', chunkArray([1, 2], 5));
console.log('Chunk size of 1:', chunkArray([1, 2, 3], 1));

// to see the output of this file use the command: node src/03-array/11-array-chunking.ts
129 changes: 129 additions & 0 deletions src/03-array/12-flatten-arrays.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// src/03-array/12-flatten-arrays.js

/**
* Flatten Nested Arrays - Convert multi-dimensional arrays into a single-dimensional array
* Common use case: Data processing, tree traversal results, nested data structures
*/

// Approach 1: Using flat() method (ES2019+)
function flattenSimple(array, depth = 1) {
return array.flat(depth);
}

// Approach 2: Deep flatten using flat(Infinity)
function flattenDeep(array) {
return array.flat(Infinity);
}

// Approach 3: Recursive approach (custom implementation)
function flattenRecursive(array) {
const result = [];

for (let item of array) {
if (Array.isArray(item)) {
result.push(...flattenRecursive(item));
} else {
result.push(item);
}
}

return result;
}

// Approach 4: Using reduce (functional approach)
function flattenReduce(array) {
return array.reduce((acc, item) => {
return acc.concat(Array.isArray(item) ? flattenReduce(item) : item);
}, []);
}

// Approach 5: Iterative approach using stack
function flattenIterative(array) {
const stack = [...array];
const result = [];

while (stack.length) {
const item = stack.pop();

if (Array.isArray(item)) {
stack.push(...item);
} else {
result.unshift(item); // Add to beginning since we're popping from end
}
}

return result;
}

// Examples
console.log('=== Flatten Arrays Examples ===\n');

const nestedArray = [1, [2, 3], [4, [5, 6]], [[[7]]], 8];
console.log('Original nested array:', JSON.stringify(nestedArray));

console.log('\nFlat with depth 1:', flattenSimple(nestedArray, 1));
// Output: [1, 2, 3, 4, [5, 6], [[7]], 8]

console.log('Flat with depth 2:', flattenSimple(nestedArray, 2));
// Output: [1, 2, 3, 4, 5, 6, [7], 8]

console.log('Deep flatten (Infinity):', flattenDeep(nestedArray));
// Output: [1, 2, 3, 4, 5, 6, 7, 8]

console.log('Recursive flatten:', flattenRecursive(nestedArray));
// Output: [1, 2, 3, 4, 5, 6, 7, 8]

console.log('Reduce flatten:', flattenReduce(nestedArray));
// Output: [1, 2, 3, 4, 5, 6, 7, 8]

console.log('Iterative flatten:', flattenIterative(nestedArray));
// Output: [1, 2, 3, 4, 5, 6, 7, 8]

// Real-world example: Flattening category hierarchies
console.log('\n=== Real-World Example: Category Hierarchy ===');

const categories = [
'Electronics',
['Computers', ['Laptops', 'Desktops', ['Gaming PCs', 'Workstations']]],
['Mobile', ['Smartphones', 'Tablets']],
'Books',
['Fiction', ['Sci-Fi', 'Fantasy']]
];

console.log('Original categories:', JSON.stringify(categories));
console.log('Flattened categories:', flattenDeep(categories));

// Performance comparison
console.log('\n=== Performance Comparison ===');

const largeNestedArray = [
[1, 2, [3, 4]],
[5, [6, [7, 8]]],
[[9, 10], 11],
[12, [13, [14, [15]]]]
];

console.time('flat(Infinity)');
flattenDeep(largeNestedArray);
console.timeEnd('flat(Infinity)');

console.time('Recursive');
flattenRecursive(largeNestedArray);
console.timeEnd('Recursive');

console.time('Reduce');
flattenReduce(largeNestedArray);
console.timeEnd('Reduce');

console.time('Iterative');
flattenIterative(largeNestedArray);
console.timeEnd('Iterative');

// Edge cases
console.log('\n=== Edge Cases ===');
console.log('Empty array:', flattenDeep([]));
console.log('Already flat array:', flattenDeep([1, 2, 3, 4]));
console.log('Array with empty arrays:', flattenDeep([1, [], [2, []], 3]));
console.log('Mixed types:', flattenDeep([1, 'hello', [true, [null, undefined]], { key: 'value' }]));

// to see the output of this file use the command: node src/03-array/12-flatten-arrays.js
Loading