Lowercase Object Keys

Beginner

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we will learn how to convert all the keys of an object to lowercase using JavaScript. This technique is particularly useful when working with data from different sources where the casing of object keys might be inconsistent.

We will utilize several JavaScript methods to accomplish this task:

  • Object.keys() to get all the keys from an object
  • Array.prototype.reduce() to transform data into a new object
  • String.prototype.toLowerCase() to convert strings to lowercase

By the end of this lab, you will be able to create a reusable function that can transform any object's keys to lowercase while preserving its values.

Understanding Objects in JavaScript

Before we start converting object keys to lowercase, let's understand what JavaScript objects are and how we can work with them.

In JavaScript, an object is a collection of key-value pairs. Keys are strings (or Symbols), and values can be any data type, including other objects.

Let's start by opening the Node.js interactive shell:

  1. Open the terminal in your WebIDE
  2. Type node and press Enter

You should now see the Node.js prompt (>), which allows you to type JavaScript code directly.

Let's create a simple object with mixed case keys:

const user = {
  Name: "John",
  AGE: 30,
  Email: "john@example.com"
};

Type this code into the Node.js prompt and press Enter. To see the object, simply type user and press Enter:

user;

You should see the output:

{ Name: 'John', AGE: 30, Email: 'john@example.com' }

As you can see, this object has keys with different casing styles. In the next step, we'll learn how to access these keys and convert them to lowercase.

Accessing Object Keys

Before we can transform object keys, we need to understand how to access them. JavaScript provides the Object.keys() method, which returns an array containing all the keys of an object.

In your Node.js interactive shell, try the following:

Object.keys(user);

You should see an output like this:

[ 'Name', 'AGE', 'Email' ]

Now, let's try converting each key to lowercase using the toLowerCase() method. We can use the map() method to transform each key:

Object.keys(user).map((key) => key.toLowerCase());

The output should be:

[ 'name', 'age', 'email' ]

Great! We now have an array with all the keys converted to lowercase. However, we still need to create a new object with these lowercase keys and the original values. For this, we'll use the reduce() method in the next step.

Let's understand the reduce() method before moving forward. This method executes a reducer function on each element of the array, resulting in a single output value.

Here's a simple example of reduce():

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((accumulator, currentValue) => {
  return accumulator + currentValue;
}, 0);

sum;

The output will be 10, which is the sum of all numbers in the array. The 0 in the reduce() method is the initial value of the accumulator.

Creating the Lowercase Function

Now that we understand how to access object keys and use the reduce() method, let's create a function that converts all keys of an object to lowercase.

In your Node.js interactive shell, define the following function:

const lowerizeKeys = (obj) => {
  return Object.keys(obj).reduce((acc, key) => {
    acc[key.toLowerCase()] = obj[key];
    return acc;
  }, {});
};

Let's break down what this function does:

  1. Object.keys(obj) gets all the keys of the input object
  2. .reduce() transforms these keys into a new object
  3. For each key, we create a new entry in the accumulator object (acc) with:
    • The key converted to lowercase using key.toLowerCase()
    • The original value from the input object (obj[key])
  4. We start with an empty object {} as the initial value for the accumulator
  5. Finally, we return the accumulator, which is our new object with lowercase keys

Now, let's test our function with the user object we created earlier:

const lowercaseUser = lowerizeKeys(user);
lowercaseUser;

You should see the output:

{ name: 'John', age: 30, email: 'john@example.com' }

Perfect! All the keys are now in lowercase.

Let's try another example to make sure our function works correctly:

const product = {
  ProductID: 101,
  ProductName: "Laptop",
  PRICE: 999.99
};

lowerizeKeys(product);

The output should be:

{ productid: 101, productname: 'Laptop', price: 999.99 }

Our function works correctly for different objects with various key casing styles.

Handling Edge Cases

Our function works well for simple objects, but what about more complex cases? Let's explore some edge cases and see how our function handles them.

Empty Objects

First, let's test with an empty object:

lowerizeKeys({});

The output should be an empty object:

{}

Objects with Nested Objects

What if the object contains nested objects? Let's try that:

const nestedObject = {
  User: {
    Name: "John",
    Contact: {
      EMAIL: "john@example.com",
      PHONE: "123-456-7890"
    }
  }
};

lowerizeKeys(nestedObject);

The output will be:

{ user: { Name: 'John', Contact: { EMAIL: 'john@example.com', PHONE: '123-456-7890' } } }

Notice that only the top-level key User is converted to lowercase. The keys inside the nested objects remain unchanged.

To handle nested objects, we would need to modify our function to recursively process all objects. Let's create an enhanced version:

const deepLowerizeKeys = (obj) => {
  return Object.keys(obj).reduce((acc, key) => {
    const value = obj[key];
    // Check if the value is an object and not null
    const newValue =
      value && typeof value === "object" && !Array.isArray(value)
        ? deepLowerizeKeys(value)
        : value;

    acc[key.toLowerCase()] = newValue;
    return acc;
  }, {});
};

This enhanced function:

  1. Checks if each value is also an object (and not an array or null)
  2. If it is, it recursively calls itself on that nested object
  3. Otherwise, it uses the original value

Let's test it with our nested object:

const deepLowerizedObject = deepLowerizeKeys(nestedObject);
deepLowerizedObject;

Now you should see all keys converted to lowercase, even in nested objects:

{ user: { name: 'John', contact: { email: 'john@example.com', phone: '123-456-7890' } } }

Great job! You've created an advanced function that can handle nested objects.

Creating a Reusable Module

Now that we have working functions, let's create a reusable JavaScript module file that we can import into other projects.

First, let's exit the Node.js interactive shell by pressing Ctrl+C twice or typing .exit and pressing Enter.

Now, create a new file named object-utils.js in the project directory:

  1. In the WebIDE, navigate to the file explorer panel on the left
  2. Right-click in the project directory and select "New File"
  3. Name the file object-utils.js
  4. Add the following code to the file:
/**
 * Converts all keys of an object to lowercase
 * @param {Object} obj - The input object
 * @returns {Object} A new object with all keys in lowercase
 */
const lowerizeKeys = (obj) => {
  return Object.keys(obj).reduce((acc, key) => {
    acc[key.toLowerCase()] = obj[key];
    return acc;
  }, {});
};

/**
 * Recursively converts all keys of an object and its nested objects to lowercase
 * @param {Object} obj - The input object
 * @returns {Object} A new object with all keys in lowercase (including nested objects)
 */
const deepLowerizeKeys = (obj) => {
  return Object.keys(obj).reduce((acc, key) => {
    const value = obj[key];
    // Check if the value is an object and not null
    const newValue =
      value && typeof value === "object" && !Array.isArray(value)
        ? deepLowerizeKeys(value)
        : value;

    acc[key.toLowerCase()] = newValue;
    return acc;
  }, {});
};

// Export the functions
module.exports = {
  lowerizeKeys,
  deepLowerizeKeys
};

Now, let's create a test file to verify that our module works correctly. Create a new file named test.js:

  1. In the WebIDE, navigate to the file explorer panel on the left
  2. Right-click in the project directory and select "New File"
  3. Name the file test.js
  4. Add the following code to the file:
// Import the functions from our module
const { lowerizeKeys, deepLowerizeKeys } = require("./object-utils");

// Test with a simple object
const user = {
  Name: "John",
  AGE: 30,
  Email: "john@example.com"
};

console.log("Original object:");
console.log(user);

console.log("\nObject with lowercase keys:");
console.log(lowerizeKeys(user));

// Test with a nested object
const nestedObject = {
  User: {
    Name: "John",
    Contact: {
      EMAIL: "john@example.com",
      PHONE: "123-456-7890"
    }
  }
};

console.log("\nNested object:");
console.log(nestedObject);

console.log("\nNested object with lowercase keys (shallow):");
console.log(lowerizeKeys(nestedObject));

console.log("\nNested object with lowercase keys (deep):");
console.log(deepLowerizeKeys(nestedObject));

Now, let's run the test file:

node test.js

You should see output similar to:

Original object:
{ Name: 'John', AGE: 30, Email: 'john@example.com' }

Object with lowercase keys:
{ name: 'John', age: 30, email: 'john@example.com' }

Nested object:
{
  User: {
    Name: 'John',
    Contact: { EMAIL: 'john@example.com', PHONE: '123-456-7890' }
  }
}

Nested object with lowercase keys (shallow):
{
  user: {
    Name: 'John',
    Contact: { EMAIL: 'john@example.com', PHONE: '123-456-7890' }
  }
}

Nested object with lowercase keys (deep):
{
  user: {
    name: 'John',
    contact: { email: 'john@example.com', phone: '123-456-7890' }
  }
}

Congratulations! You've successfully created a reusable JavaScript module with functions to convert object keys to lowercase. This module can now be imported into any of your JavaScript projects.

Summary

In this lab, you have learned how to convert object keys to lowercase in JavaScript. You have:

  1. Explored JavaScript objects and how to access their keys
  2. Used the Object.keys() method to get all keys from an object
  3. Utilized the reduce() method to transform an object
  4. Created a function to convert all keys of an object to lowercase
  5. Enhanced the function to handle nested objects recursively
  6. Created a reusable JavaScript module with both functions

These techniques are useful when working with data from different sources where the casing of object keys might be inconsistent. The functions you created can help normalize the data and make it easier to work with.

You can further extend these utilities by adding more functions, such as:

  • Converting object keys to uppercase
  • Converting keys to camelCase or snake_case
  • Filtering objects based on key or value criteria
  • Deeply comparing objects for equality

Continue practicing with objects and their manipulation to become more proficient in JavaScript programming.