JavaScript
Object Array
Property Values
Array Manipulation
Data Extraction

Get an array of property values from an object array

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Extracting an array of property values from an array of objects is one of the most common data transformation tasks in JavaScript. The standard approach is array.map(obj => obj.property), which creates a new array containing only the specified property from each object. For nested properties, optional chaining (?.) prevents errors on missing keys. Destructuring, Array.from(), and lodash's _.map or _.pluck offer alternative patterns for different use cases.

javascript
1const users = [
2    { id: 1, name: "Alice", age: 30 },
3    { id: 2, name: "Bob", age: 25 },
4    { id: 3, name: "Charlie", age: 35 },
5];
6
7// Extract names
8const names = users.map(user => user.name);
9console.log(names); // ["Alice", "Bob", "Charlie"]
10
11// Extract ids
12const ids = users.map(user => user.id);
13console.log(ids); // [1, 2, 3]
14
15// With destructuring
16const ages = users.map(({ age }) => age);
17console.log(ages); // [30, 25, 35]

Array.map() creates a new array by applying the callback to each element. It does not mutate the original array.

Nested Property Extraction

javascript
1const orders = [
2    { id: 1, customer: { name: "Alice", address: { city: "Portland" } } },
3    { id: 2, customer: { name: "Bob", address: { city: "Seattle" } } },
4    { id: 3, customer: { name: "Charlie" } }, // Missing address
5];
6
7// Safe nested access with optional chaining
8const cities = orders.map(o => o.customer?.address?.city);
9console.log(cities); // ["Portland", "Seattle", undefined]
10
11// Filter out undefined values
12const validCities = orders.map(o => o.customer?.address?.city).filter(Boolean);
13console.log(validCities); // ["Portland", "Seattle"]
14
15// With default value
16const citiesWithDefault = orders.map(o => o.customer?.address?.city ?? "Unknown");
17console.log(citiesWithDefault); // ["Portland", "Seattle", "Unknown"]

Optional chaining (?.) returns undefined instead of throwing a TypeError when a property in the chain is null or undefined.

Using flatMap() for Multiple Values

javascript
1const users = [
2    { name: "Alice", skills: ["JavaScript", "Python"] },
3    { name: "Bob", skills: ["Java", "Go"] },
4    { name: "Charlie", skills: ["Python", "Rust"] },
5];
6
7// Get all skills (flattened)
8const allSkills = users.flatMap(u => u.skills);
9console.log(allSkills); // ["JavaScript", "Python", "Java", "Go", "Python", "Rust"]
10
11// Unique skills
12const uniqueSkills = [...new Set(users.flatMap(u => u.skills))];
13console.log(uniqueSkills); // ["JavaScript", "Python", "Java", "Go", "Rust"]

flatMap() maps each element and then flattens the result by one level — perfect for extracting arrays from objects and merging them.

Using reduce() for Grouped Extraction

javascript
1const products = [
2    { category: "fruit", name: "Apple", price: 1.20 },
3    { category: "veggie", name: "Carrot", price: 0.80 },
4    { category: "fruit", name: "Banana", price: 0.50 },
5    { category: "veggie", name: "Broccoli", price: 1.50 },
6];
7
8// Group names by category
9const grouped = products.reduce((acc, item) => {
10    (acc[item.category] ??= []).push(item.name);
11    return acc;
12}, {});
13console.log(grouped);
14// { fruit: ["Apple", "Banana"], veggie: ["Carrot", "Broccoli"] }
15
16// Sum prices by category
17const totals = products.reduce((acc, item) => {
18    acc[item.category] = (acc[item.category] ?? 0) + item.price;
19    return acc;
20}, {});
21console.log(totals); // { fruit: 1.7, veggie: 2.3 }

Reusable Property Extractor

javascript
1// Generic function to extract a property
2const pluck = (arr, key) => arr.map(item => item[key]);
3
4console.log(pluck(users, "name")); // ["Alice", "Bob", "Charlie"]
5
6// For nested paths
7const pluckPath = (arr, path) => {
8    const keys = path.split(".");
9    return arr.map(item => keys.reduce((obj, key) => obj?.[key], item));
10};
11
12console.log(pluckPath(orders, "customer.address.city"));
13// ["Portland", "Seattle", undefined]

TypeScript Version

typescript
1interface User {
2    id: number;
3    name: string;
4    age: number;
5}
6
7const users: User[] = [
8    { id: 1, name: "Alice", age: 30 },
9    { id: 2, name: "Bob", age: 25 },
10];
11
12// Type-safe extraction — result is string[]
13const names: string[] = users.map(u => u.name);
14
15// Generic pluck with type safety
16function pluck<T, K extends keyof T>(arr: T[], key: K): T[K][] {
17    return arr.map(item => item[key]);
18}
19
20const ages = pluck(users, "age"); // number[]
21const ids = pluck(users, "id");   // number[]

Common Pitfalls

  • Missing property returns undefined: [{a:1}, {b:2}].map(o => o.a) returns [1, undefined]. Use optional chaining and filter(Boolean) or a default value to handle missing properties.
  • Mutating objects inside map(): map() should be a pure transformation. Modifying the source objects (e.g., user.name = user.name.toUpperCase()) inside the callback mutates the original array.
  • Using for...in instead of map(): for...in iterates over all enumerable properties including inherited ones. Always use map(), for...of, or forEach() for array iteration.
  • Forgetting that map() preserves array length: Unlike filter(), map() always returns an array the same length as the input. Use .filter() after .map() or .flatMap() to remove unwanted entries.
  • String property access on null/undefined: obj[key] throws if obj is null or undefined. When the array may contain null entries, filter them first or use optional chaining: arr.map(o => o?.[key]).

Summary

  • array.map(obj => obj.prop) — standard approach for extracting a property from each object
  • Use optional chaining (?.) for safe nested property access
  • flatMap() — extract and flatten array properties from objects
  • reduce() — group or aggregate property values
  • Destructuring in the callback — map(({ name }) => name) for cleaner syntax
  • Generic pluck(arr, key) function for reusable property extraction

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.