When incorporating reduce into your code, remember to expect an undefined

Imagine you have an array like this:

const novels = [
  {
    id: 1,
    name: 'The Da Vinci Code',
    genre: 'Mystery',
    author: {
      name: 'Dan Brown',
      birthYear: 1964,
    },
    releaseYear: 2003,
  },
  {
    id: 2,
    name: 'To Kill a Mockingbird',
    genre: 'Drama',
    author: {
      name: 'Harper Lee',
      birthYear: 1926,
    },
    releaseYear: 1960,
  },
  {
];

If we want to find and display the book with the longest title, we can use the following code snippet:

const findLongestTitle = () => {
  const longestTitle = novels.reduce((prevBook, currentBook) => {
      if (currentBook.name.length > prevBook.name.length) {
        return currentBook;
      }
      return prevBook;
    });
  return longestTitle
}

console.log(findLongestTitle().name);

The question at hand is why it's necessary to access .name property while calling the function instead of directly returning book.name / accumulator.name inside the function. If attempted without accessing .name, the result turns out to be undefined.

const findLongestTitle = () => {
  const longestTitle = novels.reduce((prevBook, currentBook) => {
      if (currentBook.name.length > prevBook.name.length) {
        return currentBook.name;
      }
      return prevBook.name;
    });
  return longestTitle
}

console.log(findLongestTitle());

Answer №1

When using the reduce method, you pass a single value - known as the accumulator - from one iteration to the next. It is important in well-structured reduce callbacks for the accumulator to maintain a consistent shape throughout the loop so that logic can be applied reliably and consistently.

If you attempt to only return the .name, there arise issues:

  const longestName = books.reduce((accumulator, book) => {
      if (book.name.length > accumulator.name.length) {
        return book.name;
      }
      return accumulator.name;
    });

This is problematic because:

  • Since no initial value was provided, the accumulator in the first iteration will be the first book object
  • During the first iteration, you are returning either the .name of the first book object or the second book object, resulting in the accumulator becoming a string for the subsequent iteration
  • In the second iteration, the accumulator is now a string instead of a book object, hence return accumulator.name does not yield any result.

Answer №2

When the accumulator is assigned the .name property, it transforms into a simple string and loses its ability to compare against the next iteration's .name property.

To ensure consistency in your accumulator type throughout, it is important to set an initial value right from the beginning. An empty string can serve this purpose...

return books.reduce(
  (acc, { name }) => name.length > acc ? name : acc,  
  "" // starting value
);

Answer №3

To ensure you are accumulating a string instead of an object, your entire reduce() method should be focused on that goal.

Additionally, you will need to provide an initial value for reduce(). By default, it uses the first value of the array, which is an object and not a string.

const books = [{
  id: 1,
  name: 'A song of ice and fire',
  genre: 'Fantasy',
  author: {
    name: 'George R. R. Martin',
    birthYear: 1948,
  },
  releaseYear: 1991,
}, {
  id: 2,
  name: 'The lord of the rings',
  genre: 'Fantasy',
  author: {
    name: 'J. R. R. Tolkien',
    birthYear: 1892,
  },
  releaseYear: 1954,
}];


const longestBookTitle = () => {
  const longestName = books.reduce((accumulator, { name }) => {
    if (name.length > accumulator.length) {
      return name;
    }
    return accumulator;
  }, '');
  return longestName;
}

console.log(longestBookTitle());

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The XMLHttpRequest() function throws NS_ERROR_FAILURE when sending requests to localhost using either an absolute or relative path

Encountering an error in Firefox 31 ESR: Error: NS_ERROR_FAILURE: Source file: http://localhost/Example/scripts/index.js Line: 18 Similar issue observed on Internet Explorer 11: SCRIPT5022: InvalidStateError The script used for AJAX function call i ...

Angular 12: Running ng test shows code coverage error - TypeError: Unable to access 'initialize' property as undefined

I encountered an error in the code coverage console: TypeError: Cannot read properties of undefined (reading 'initialize') I am trying to call a service method from the component.ts file The code in the component.ts file looks like: this.myAuth ...

eliminate the common elements between two arrays in typescript/javascript

I have two lists of objects, each containing two fields: let users1 = [{ name: 'barney', uuid: 'uuid3'}, { name: 'barney', uuid: 'uuid1'}, { name: 'barney', uuid: 'uuid2 ...

Learn how to utilize Javascript to easily drag and drop an image within the same block

I am encountering an issue with dragging and dropping images or swapping them using JavaScript. I have tried to implement this in the code below, where clicking on icons moves them onto a colored div. However, I am now trying to drag and drop the images wi ...

What is the process for retrieving the AJAX response text?

When it comes to my AJAX development, I rely on prototype and utilize the following code: somefunction: function(){ var result = ""; myAjax = new Ajax.Request(postUrl, { method: 'post', postBody: postData, content ...

Passing an unpredictable amount of parameters to react router in a dynamic way

Within my React application, users have the ability to create both folders and files. A folder can contain an indefinite number of subfolders within it. Here is an example structure: Folder-1 |_Folder-1-1 |_Folder-1-2 |_Folder-1-2-1 |_Folder- ...

Is it possible to incorporate multiple searchBoxes on my website using the Google Maps API?

I am currently working on creating an origin and destination menu for users to select locations in each input. The goal is to add a marker to the map for each input and then calculate the distance between them. So far, I have successfully added a map with ...

Attempting to modify the background hue of a grid component when a click event is triggered

I am struggling with the syntax to change the color of an element in my grid when clicked. I have attempted different variations without success. Being new to JavaScript, I would appreciate some gentle guidance if the solution is obvious. JS const gri ...

Vue JS ensures that it has all the necessary data before proceeding with the

I've been grappling with a VueJS data rendering issue for a few weeks now. My approach involves making axios calls, some nested within others. The problem I'm facing is that the data renders before the calls have completed, resulting in an empty ...

What is the best way to specify a function parameter as a Function type in TypeScript?

I'm currently delving into the world of TypeScript and I am unsure about how to specify a function parameter as a function type. For instance, in this piece of code, I am passing a setState function through props to a child component. const SelectCity ...

Is there a way to set columns as initially hidden in MaterialTable?

I have a MaterialTable with many columns, and some of them are not always necessary to display. I am looking for a way to hide these columns unless the user specifically selects them. I attempted to use the hidden: true property in the column configuratio ...

Minimize the number of HTTP requests by including CSS and JS files in PHP

I've been considering a method to reduce the number of HTTP requests made when loading a page by minimizing the amount of downloaded files, while still keeping separate files on the server. The thought process is as follows: <!DOCTYPE html> &l ...

Can JSON-formatted JavaScript variables be inserted and utilized in MongoDB?

I am currently in the process of formatting a large JavaScript file so that I can insert it into a MongoDB collection and retrieve it using AJAX. However, I am encountering issues with the syntax. Here is an example snippet: var MyData = [ { Elements: ...

Validation of input using JQuery

I am currently working on validating a form, with a specific field that needs to be required. Here is the code for the field in question: <p> <label for="lf">Name: </label> <input class="lf" name="name" type="text"/> < ...

Sequelize.Model not being recognized for imported model

I am encountering an issue while trying to implement a sequelize N:M relation through another table. The error message I keep receiving is as follows: throw new Error(${this.name}.belongsToMany called with something that's not a subclass of Sequelize ...

Click text when using the Google Tag Manager - gtm.click {{Click Text}}

I have a list of shops with detailed information like opening hours and phone numbers. When a user clicks on the shop's name, I want the relevant details to appear using javascript. I am trying to capture the shop's name (SHOP NAME) when a user ...

`What is the process for accessing page-specific data on Google Analytics using the analyticsreporting tool?`

I'm currently working on extracting specific analytics data using Google's analyticsreporting API v4. Below are the URLs of the pages I am analyzing: https://www.example.com/uiqueId1 https://www.example.com/uiqueId2 https://www.example.com/uiqu ...

Implementing non-blocking asynchronous object return in a node.js function

Struggling with a function that accesses data from a JSON file and queries it for a specific key. Unfortunately, the return function seems to be executing before the query can find the key. Even after querying and attempting to return the variable queryre ...

Injecting dynamic data into a function parameter with Angular 1 Interpolation

In my code, I have a feature that alters the text displayed on a button depending on certain conditions. $scope.text = 'Wait'; if(Number($scope.x) == Number($scope.y)) $scope.text = 'Go' else if(Number($scope.x) < Number($scope ...

What is the reason for the failure of this JavaScript promise?

Currently studying the concept of promises. app.get('/message',function(req, res){ var promise = new Promise(function(resolve, reject){ resolve("hi"); }); promise.then(function(message){ res.json(message); }) ...