How to recursively map object in JavaScript [SOLVED]


Written By - Olorunfemi Akinlua

Introduction

Recursive mapping is a technique for traversing an object and applying a function to each of its properties, including nested properties. In JavaScript, this can be useful for transforming complex data structures, extracting specific information, or simply performing an operation on all properties of an object.

One common use case for recursive mapping is to transform an object into a new object with a different structure or format. In this article, we will discuss how to achieve recursive map object operations in JavaScript.

 

Achieving recursive map object operation in JavaScript

Example-1

For example, consider an object representing a list of employees in an organization, with properties such as name, title, and department. If we wanted to create a new object that only includes the names and titles of the employees, we could use a recursive map function to iterate over the object and return a new object with the desired properties.

To implement a recursive map function in JavaScript, we can use a function that takes two arguments: the object to map and the transformation function to apply to each property. The function should first check if the object is a primitive value (such as a string, number, or boolean); if it is, it should return the result of applying the transformation function to that value. If the object is not a primitive value, the function should iterate over the object's properties and apply the transformation function recursively to each one.

Here is an example of a map function that creates a new object with only the name and title properties of an input object

function mapObject(obj, fn) {
    return Object.keys(obj).reduce((acc, key) => {
        acc[key] = fn(obj[key]);
        return acc;
    }, {});
}

This code defines a function called mapObject that takes in an object and a callback function. It uses the Object.keys() method to get an array of the keys of the input object, then it uses the reduce() method to iterate over the array of keys, creating a new object.

For each key, it uses the key to access the corresponding value in the input object and calls the callback function passed as an argument, passing in that value as the argument. Then it assigns the returned value of the callback function to the same key in the new object. This process continues for every key in the input object, resulting in a new object that contains the key-value pairs returned by the callback function. The new object is returned by the mapObject function.

In this case, the callback function passed to the mapObject function is a function that returns an object with name and title properties, which is called on each employee object, resulting in a new object with the same keys but with the properties 'name' and 'title' only.

To use this function, we can pass in an object and a transformation function that extracts the name and title properties:

function mapObject(obj, fn) {
    return Object.keys(obj).reduce((acc, key) => {
        acc[key] = fn(obj[key]);
        return acc;
    }, {});
}
const employees = {
    alice: { name: "Alice", title: "Manager", department: "Marketing" },
    bob: { name: "Bob", title: "Developer", department: "Engineering" },
    charlie: { name: "Charlie", title: "Manager", department: "Marketing" },
    dave: { name: "Dave", title: "Designer", department: "Design" },
};

const namesAndTitles = mapObject(employees, (employee) => ({
    name: employee.name,
    title: employee.title,
}));

console.log(namesAndTitles);

Output

{
  alice: { name: 'Alice', title: 'Manager' },
  bob: { name: 'Bob', title: 'Developer' },
  charlie: { name: 'Charlie', title: 'Manager' },
  dave: { name: 'Dave', title: 'Designer' }
}

This map function can be useful in a variety of situations where you need to transform an object into a new object with a different structure or format. It is a powerful tool for manipulating complex data structures and extracting specific information from objects.

Now, we can create a recursive mapping function to perform an operation on all properties of an object, regardless of their type or nesting level. For example, we might want to convert all property values to uppercase, or add a prefix to all property names. To do this, we can modify the transformation function to perform the desired operation on each value or key.

 

Example-2

Here is an example of a recursive map function that converts all property values to uppercase

function mapObject(obj, fn) {
    if (typeof obj !== "object" || obj === null) {
        return fn(obj);
    }
    const mapped = {};
    for (const [key, value] of Object.entries(obj)) {
        mapped[key] = mapObject(value, fn);
    }
    return mapped;
}

const employees = {
    alice: { name: "Alice", title: "Manager", department: "Marketing" },
    bob: { name: "Bob", title: "Developer", department: "Engineering" },
    charlie: { name: "Charlie", title: "Manager", department: "Marketing" },
    dave: { name: "Dave", title: "Designer", department: "Design" },
};

const uppercaseValues = mapObject(employees, (value) =>
    typeof value === "string" ? value.toUpperCase() : value
);

console.log(uppercaseValues);

Output

{
  alice: { name: 'ALICE', title: 'MANAGER', department: 'MARKETING' },
  bob: { name: 'BOB', title: 'DEVELOPER', department: 'ENGINEERING' },
  charlie: { name: 'CHARLIE', title: 'MANAGER', department: 'MARKETING' },
  dave: { name: 'DAVE', title: 'DESIGNER', department: 'DESIGN' }
}

In this example, the transformation function uses the typeof operator to check if the value is a string, and converts it to uppercase if it is. If the value is not a string, it is returned as is.

 

Example-3

In this function mapObjectRecursively takes two arguments, an object obj and a callback function. The function first creates an empty object newObj. It then uses a for...in loop to iterate over each key in the original object. If the current key's value is an object, the function calls itself recursively on that object. If the current key's value is not an object, the function calls the callback function on the value and assigns the result to the corresponding key in the new object. The final result is the new object with all of its properties mapped using the callback function.

function mapObjectRecursively(obj, callback) {
    let newObj = {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (typeof obj[key] === "object") {
                newObj[key] = mapObjectRecursively(obj[key], callback);
            } else {
                newObj[key] = callback(obj[key]);
            }
        }
    }
    return newObj;
}

let originalObj = {
    a: 1,
    b: {
        c: 2,
        d: {
            e: 3
        }
    },
    f: 4
};

let newObj = mapObjectRecursively(originalObj, value => value * 2);
console.log(newObj);

Output:

{ a: 2, b: { c: 4, d: { e: 6 } }, f: 8 }

 

Example-4

One alternative method is to use the Object.entries() method to get an array of the object's key-value pairs, and then use the Array.prototype.map() method to recursively map the object's properties. Here is an example to perform recursive search in map object:

let myObj = {
  a: 1,
  b: {
    c: 2,
    d: 3
  },
  e: 4
};

function recursiveMap(obj, callback) {
  // Use Object.entries() to get an array of the object's key-value pairs
  Object.entries(obj).forEach(([key, val]) => {
    // If the value is an object, recursively call the function with that object as the new argument
    if (typeof val === 'object') {
      obj[key] = recursiveMap(val, callback);
    } 
    // If the value is not an object, call the callback function with that value as the argument,
    // and assign the result of the callback to the property
    else {
      obj[key] = callback(val);
    }
  });
  console.log(obj)
   // Return the mapped object
  return obj;
}


let mappedObj = recursiveMap(myObj, (val) => val * 2);
console.log(mappedObj); // { a: 2, b: { c: 4, d: 6 }, e: 8 }

In this example, the recursiveMap function takes an object and a callback function as its arguments. The function uses the Object.entries() method to get an array of the object's key-value pairs. Then it uses the Array.prototype.forEach() method to iterate through the array.

For each key-value pair, it checks if the value is an object using typeof operator. If the value is an object, the function calls itself recursively with that object as the new argument. If the value is not an object, the function calls the callback function with that value as the argument, and assigns the result of the callback to the property. Finally it returns the mapped object.

 

Summary

Recursive mapping is a powerful technique for traversing and manipulating objects in JavaScript. It allows you to apply a transformation function to all properties of an object, including nested properties and can be used to extract specific information, transform data structures, or perform operations on all properties.

In summary, recursive mapping is a technique for traversing an object and applying a function to each of its properties, including nested properties. It is useful for transforming complex data structures, extracting specific information, or performing operations on all properties of an object. By using a recursive map function, developers can easily manipulate and transform complex data structures in JavaScript.

 

References

Recursion - MDN Web Docs Glossary: Definitions of Web-related terms | MDN (mozilla.org)

 

Olorunfemi Akinlua

He is boasting over five years of experience in JavaScript, specializing in technical content writing and UX design. With a keen focus on programming languages, he crafts compelling content and designs user-friendly interfaces to enhance digital experiences across various domains. You can connect with him on LinkedIn.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment