Array methods

Object and array destructuring enables developers to unpack values from objects and arrays and assign them to variables in a more concise and readable manner.

Learning Goals

At the end of this Tutorial, you will be able to:

  • Destructure an object.
  • Destructure an array.
  • Use the ... (rest) operator with arrays.

The array.filter() method

Use the array.filter() method to:

  • Make a copy of an array that includes
  • Only those items that pass the test implemented by the provided function.

The original array is unaffected.

screenshot

The simplest syntax is a follows:

const newArray = oldArray.filter(callbackFunction)

The callbackFunction argument passed to the .filter() method could be:

  • A simple, one-line arrow function such as below.
       const newArray = oldArray.map(item => item * 2)
  • An multi-line arrow function with code wrapped inside a {}. You need to include a return statement if you want the output to be used elsewhere in the code. See below.
       const celsiusTemps = [0, 25, 30, 100];
    
    const fahrenheitTemps = celsiusTemps.map(temp => {
        // Assign each item of new array to a variable named temp
        const fahrenheit = (temp * 9/5) + 32;
        return `${temp}°C is ${fahrenheit}°F`;
    });
        
    console.log(fahrenheitTemps);  
    // Outputs: ["0°C is 32°F", "25°C is 77°F", "30°C is 86°F", "100°C is 212°F"]
    Note that you're not re-declaring the fahrenheit variable in the same scope multiple times. On each iteration through celsiusTemps array, a new scope is created by the {}, allowing for a new fahrenheit variable to be declared without any conflicts with the previous one. In short, you're declaring the variable in different, unique scopes for each iteration of the loop.   Use this multi-line format when the transformation logic inside the .map() loop is a bit more complex or needs multiple lines.
  • An external function declared elsewhere in the code. For example.
       // Original array of radius values
    const radii = [5, 10, 15];
    
    // Function to calculate the area of a circle
    function circleArea(radius) {
       return Math.PI * radius * radius;
    }
                    
    // Apply the area calculation function to each item in the new array named radii
    const areas = radii.map(circleArea);
    console.log(`Circle 1 radius: ${radii[0]} Circle area: ${areas[0].toFixed(4)}`);  
    console.log(`Circle 2 radius: ${radii[1]} Circle area: ${areas[1].toFixed(4)}`);  
    console.log(`Circle 3 radius: ${radii[2]} Circle area: ${areas[2].toFixed(4)}`); 
    // Outputs:
    // Circle 1 radius: 5 Circle area: 78.5398
    // Circle 2 radius: 10 Circle area: 314.1593
    // Circle 3 radius: 15 Circle area: 706.8583
    In the above example, for each item in the array:
    • The .map() method calls the circleArea() function, and
    • Passes the array item as the input parameter to that function.
    The function is not immediately invoked by .map() but is passed by reference to it as an argument and runs outside the .map() loop. The function's output is then returned to the loop.   You could rewrite this as a one-line arrow function as follows:
       const areas = radii.map(radii => { return Math.PI * radii * radii });
    Or even more concisely as follows:
       const areas2 = radii.map(radii => Math.PI * radii * radii);
    But when the transformation logic is complex or needs to be reused elsewhere in the code, it makes sense to place it in a separate function outside the .map() loop. This pattern can make your code more modular and readable.

Mapping arrays of strings

The first example below simply outputs an unchanged copy of the array. Each element in the copied array MyList1 is the same as in the original myArray1 array.

const myArray1 = ['apple', 'banana', 'orange'];

// Just copy original array - don't change its items
const myList1 = myArray1.map(item => item);
console.log(myList1);
// Outputs ['apple', 'banana', 'orange']

Below is an example where the items in the copied array are different. They are capitalised by the arrow function inside the loop.

myArray3 = ['apple', 'banana', 'orange'];

// Capitalise each item in the copied array
const myList3 = myArray3.map(item => item.toUpperCase());
console.log(myList3);
// Outputs ['APPLE', 'BANANA', 'ORANGE']

Mapping arrays of numbers

In the first example below, each item in the copied array is doubled by the arrow function inside the loop. In the second example, each item in the copied array has the number three added to it.

const numbers = [1, 2, 3, 4, 5];

// Multiply each item in the copied array by 2
const doubled = numbers.map(number => number * 2);
console.log(doubled);
// Outputs [2, 4, 6, 8, 10]

// Add 3 to each item in the copied array
const plusThree = numbers.map(number => number + 3);
console.log(plusThree);
// Outputs [4, 5, 6, 7, 8]

Mapping arrays of objects

You can use the .map() method with arrays of objects. See the two examples below.

const users = [
   { firstName: "Susan", lastName: "Steward", age: 14, hobby: "Singing" },
   { firstName: "Daniel", lastName: "Longbottom", age: 16, hobby: "Football" },
   { firstName: "Jacob", lastName: "Black", age: 15, hobby: "Singing" }
];

// In the copied array the firstName and lastName item properties are output together 
const fullNames = users.map(user => console.log(`${user.firstName} ${user.lastName}`));
// Outputs:
// Susan Steward
// Daniel Longbottom
// Jacob Black
const products = [
    { id: 1, name: 'Laptop', price: 1000 },
    { id: 2, name: 'Mouse', price: 50 },
    { id: 3, name: 'Keyboard', price: 70 }
];

// Apply 10% discount to each item in the copied array
const specialOffers = products.map(product => {
    console.log(`${product.name} (id: ${product.id}) Sale price! €${product.price * 0.9}`);
});
// Outputs:
// Laptop (id: 1) Sale price! €900
// Mouse (id: 2) Sale price! €45
// Keyboard (id: 3) Sale price! €63

Mapping arrays with the ternary :; operator

Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ratione dicta blanditiis amet veritatis sed commodi exercitationem deserunt eos nisi ipsam tempora, recusandae facilis mollitia quisquam nesciunt expedita. Obcaecati, totam repudiandae.

Mapping arrays with the short-circuit && operator

Lorem ipsum dolor sit, amet consectetur adipisicing elit. Cupiditate cumque repudiandae consequatur totam, mollitia, temporibus rem sed expedita fugit ullam impedit aperiam minus id inventore, quas tenetur aspernatur assumenda natus.

About object destructuring

Array destructuring enables developers to unpack values from arrays and assign them to variables in a more concise and readable manner.

Basic object destructuring

Consider the following object:

const person = {
   name: "John",
   age: 25,
   location: "New York"
};

Without destructuring, if you wanted to assign these properties to individual variables, you'd do:

const name = person.name;
const age = person.age;
const location = person.location;

With object destructuring, you can simplify this to:

const { name, age, location } = person;

Each variable will now hold the value from the corresponding property in the object.

Renaming variables

Sometimes, you might want to assign properties to variables with different names. Object destructuring allows for renaming:

const { name: firstName, age: yearsOld } = person;

How it relates to React.js props

In React.js, components often receive data via props. Object destructuring becomes particularly handy when working with function components and their props.

Consider the following function component/

function Welcome(props) {
   return <h1>htHello, {props.name}!>/h1>;
}

Using object destructuring, you can simplify the function signature and directly extract the required props:

function Welcome({ name }) {
  return <h1>Hello, {name}!</h1>;
}

This way, you don't have to repeatedly prefix with props. when accessing the properties. It makes the component more readable, especially when dealing with multiple props.

About array destructuring

Array destructuring enables developers to unpack values from arrays and assign them to variables in a more concise and readable manner.

When working with hooks such as useState in React.js, array destructuring becomes especially handy. For example:

const [count, setCount] = useState(0);

Here, useState returns an array where the first item is the current state (count) and the second item is a function to update that state (setCount). Using array destructuring enables you to neatly assign these to variables in one line.

Basic array destructuring

Suppose you have the following array:

const colors = ["red", "green", "blue"];

Without destructuring, if you wanted to assign these colors to individual variables, you would do:

const firstColor = colors[0];
const secondColor = colors[1];
const thirdColor = colors[2];

With array destructuring, this can be simplified to:

const [firstColor, secondColor, thirdColor] = colors;

Here, firstColor will be "red", secondColor will be "green", and thirdColor will be "blue".

Skipping items in an array

You can skip items in the array if you're only interested in certain values:

const [firstColor, , thirdColor] = colors;

Using the ... (rest) operator

To gather the remaining items in an array, use the ... (rest) operator:

const colors = ["red", "green", "blue", "yellow"];
const [firstColor, ...otherColors] = colors;

Here, firstColor will be "red", and otherColors will be an array containing ["green", "blue", "yellow"].

This understanding of array destructuring is crucial in React, as it provides a clean and efficient way to manage and update component state.

When working with hooks such as useState in React.js, array destructuring becomes especially handy. For example:

const [count, setCount] = useState(0);

Here, useState returns an array where the first item is the current state (count) and the second item is a function to update that state (setCount). Using array destructuring enables you to neatly assign these to variables in one line.