Mastering Objects, Arrays, and the Art of Data Manipulation
The Building Blocks of Complex Data
An object is a collection of related data and/or functionality. These consist of several variables and functions (which are called properties and methods when they are inside objects).
It's how we model real-world things, like a user, a product, or a server configuration.
const user = {
id: 'a1b2c3d4',
username: 'arch_dev',
email: 'architect@example.com',
isActive: true,
login: function() {
console.log(`${this.username} has logged in.`);
}
};
There are two ways to access an object's properties. Understanding when to use each is crucial.
Simple, clean, and the most common way.
console.log(user.username); // arch_dev
Limitation: The property name must be a valid JavaScript identifier and you must know it beforehand.
More powerful and flexible.
console.log(user['email']); // architect@example.com
const keyToAccess = 'isActive';
console.log(user[keyToAccess]); // true
Use when: The property name is stored in a variable, or contains spaces or special characters.
You can use bracket notation during object creation to dynamically set property keys.
const role = 'admin';
const id = 123;
const user = {
[role]: 'Super User', // Property is named 'admin'
[`user_${id}`]: { status: 'active' } // Property is named 'user_123'
};
console.log(user.admin); // "Super User"
console.log(user.user_123.status); // "active"
This is extremely useful when creating objects from dynamic data.
Ordered Collections of Data
An array is a special type of object used for storing an ordered list of values. Each value is called an element, and each element has a numeric index, starting from zero.
// An array of strings
const roles = ['admin', 'editor', 'viewer'];
// An array of numbers
const accessLevels = [1, 2, 3, 4];
// An array of objects
const users = [
{ id: 1, name: 'Alex' },
{ id: 2, name: 'Jane' }
];
// Accessing by index
console.log(roles[0]); // 'admin'
console.log(users[1].name); // 'Jane'
These methods change the original array. Use them with care.
const tasks = ['Code', 'Test'];
tasks.push('Deploy'); // ['Code', 'Test', 'Deploy']
tasks.shift(); // ['Test', 'Deploy']
The Modern Way to Process Data
A core principle of functional programming is immutability. Instead of changing your original data, you create new data based on the original.
The methods we are about to see do not change the original array. They return a brand new array (or value).
This makes code safer, more predictable, and easier to debug.
The simplest functional method. It executes a provided function once for each array element. It's a modern alternative to a basic `for` loop.
It does not return a new array; it always returns `undefined`.
const users = ['Alex', 'Jane', 'Peter'];
users.forEach(function(user, index) {
console.log(`User #${index + 1} is ${user}`);
});
// Output:
// User #1 is Alex
// User #2 is Jane
// User #3 is Peter
The most important transformation method. It creates a new array populated with the results of calling a provided function on every element in the calling array.
Use it when you want to convert an array of one thing into an array of another thing.
const numbers = [1, 4, 9, 16];
// Create a new array of the square roots
const roots = numbers.map(function(num) {
return Math.sqrt(num);
});
console.log(roots); // [1, 2, 3, 4]
console.log(numbers); // [1, 4, 9, 16] (Original is unchanged!)
Creates a new array with all elements that pass the test implemented by the provided function. The callback must return a boolean.
Use it when you want to select a subset of an array based on a condition.
const products = [
{ name: 'Laptop', price: 1200, inStock: true },
{ name: 'Mouse', price: 40, inStock: false },
{ name: 'Keyboard', price: 100, inStock: true }
];
const availableProducts = products.filter(function(product) {
return product.inStock === true;
});
// availableProducts is a new array with only the Laptop and Keyboard
The most powerful but complex method. It executes a "reducer" function on each element of the array, resulting in a single output value.
Use it to "boil down" an array to one value (e.g., a sum, an object, a string).
const cart = [ { price: 10 }, { price: 25 }, { price: 15 } ];
// The `accumulator` is the value returned from the last iteration.
// The `currentItem` is the current element being processed.
// `0` is the initial value of the accumulator.
const total = cart.reduce(function(accumulator, currentItem) {
return accumulator + currentItem.price;
}, 0);
console.log(total); // 50
These methods are for asking questions about your array.
The real power of functional methods comes from chaining them together. Because methods like `map` and `filter` return new arrays, you can immediately call another array method on the result.
This creates elegant, readable, and powerful data processing pipelines.
const users = [
{ id: 1, name: 'Alex', role: 'admin', age: 30 },
{ id: 2, name: 'Jane', role: 'editor', age: 25 },
{ id: 3, name: 'Peter', role: 'admin', age: 42 }
];
// Get the names of all admins over the age of 35, in uppercase.
const adminNames = users
.filter(user => user.role === 'admin')
.filter(admin => admin.age > 35)
.map(admin => admin.name.toUpperCase());
console.log(adminNames); // ['PETER']
Your task is to use functional array methods to process a list of transactions and generate a report. This is a very common backend task.
Calculate the total amount from all successful debit transactions over $50, and return it as a formatted currency string.
$270.00
const transactions = [
{ id: 't1', type: 'debit', status: 'success', amount: 150 },
{ id: 't2', type: 'credit', status: 'success', amount: 200 },
{ id: 't3', type: 'debit', status: 'failed', amount: 100 },
{ id: 't4', type: 'debit', status: 'success', amount: 35 },
{ id: 't5', type: 'debit', status: 'success', amount: 120 },
];
// Your chained method solution goes here!
// const finalReport = transactions
// .filter(...)
// .filter(...)
// .map(...)
// .reduce(...);
//
// After reduce, format the final number.
// Hint: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(number);
// console.log(finalReport);
Hint: You will need `filter` (twice), `map`, and `reduce`.
You can now transform, select, and aggregate complex data with clarity and precision. This is a superpower.