josh_c
josh_c

Reputation: 149

Javascript tutorial, having trouble mapping & reducing to get correct answer

I'm trying to complete this tutorial, but I cannot figure out why the answer the instructor gave is not working for me.

There is an array of users (objects) that each have favoriteBooks as nested objects.

We are to use map and reduce to create an array of all favorite books from all users.

The code I have on the bottom is what I have so far, but is also what the instructor said the solution is. His code worked to create the exact solution (on his video).

However, I think the problem is when the second map comes into play, there is still another level of nested arrays to get through.

Can someone please shed some light on this? I cannot figure it out for the life of me.

Thanks!

const users = [
  {
    name: 'Samir',
    age: 27,
    favoriteBooks:[
      {title: 'The Iliad'},
      {title: 'The Brothers Karamazov'}
    ]
  },
  {
    name: 'Angela',
    age: 33,
    favoriteBooks:[
      {title: 'Tenth of December'},
      {title: 'Cloud Atlas'},
      {title: 'One Hundred Years of Solitude'}
    ]
  },
  {
    name: 'Beatrice',
    age: 42,
    favoriteBooks:[
      {title: 'Candide'}
    ]
  }
];

    // Result: ['The Iliad', 'The Brothers Karamazov', 'Tenth of December', 'Cloud Atlas', 'One Hundred Years of Solitude', 'Candide'];

var books = users
  .map(function(user) {
    return user.favoriteBooks;
  })
  .map(function(book) {
    return book.title;
  })
  .reduce(function(arr, titles) {
    return [ ...arr, ...titles ];
  }, []);

console.log(books);

Upvotes: 0

Views: 37

Answers (3)

ashwintastic
ashwintastic

Reputation: 2312

const users = [
    {
        name: 'Samir',
        age: 27,
        favoriteBooks:[
            {title: 'The Iliad'},
            {title: 'The Brothers Karamazov'}
        ]
    },

    {
        name: 'Angela',
        age: 33,
        favoriteBooks:[
            {title: 'Tenth of December'},
            {title: 'Cloud Atlas'},
            {title: 'One Hundred Years of Solitude'}
        ]
    },
    {
        name: 'Beatrice',
        age: 42,
        favoriteBooks:[
            {title: 'Candide'}
        ]
    }
];

const array = users.reduce((arr, val) => {
    val.favoriteBooks.map ( (t) =>{
        arr.push(t.title)
    })
    return arr
}, []);

console.log( array)

Upvotes: 0

Dez
Dez

Reputation: 5838

You need the reduce function to flatten the nested array and the map function to return the book titles for each user inside the reducer. Then finally with a bit of spread operator you can fill up the accumulator (arr) of the reducer and get the whole list.

const users = [
  {
    name: 'Samir',
    age: 27,
    favoriteBooks:[
      {title: 'The Iliad'},
      {title: 'The Brothers Karamazov'}
    ]
  },
  {
    name: 'Angela',
    age: 33,
    favoriteBooks:[
      {title: 'Tenth of December'},
      {title: 'Cloud Atlas'},
      {title: 'One Hundred Years of Solitude'}
    ]
  },
  {
    name: 'Beatrice',
    age: 42,
    favoriteBooks:[
      {title: 'Candide'}
    ]
  }
];

    // Result: ['The Iliad', 'The Brothers Karamazov', 'Tenth of December', 'Cloud Atlas', 'One Hundred Years of Solitude', 'Candide'];

const books = users
  .reduce((arr, user) => {
    const favBooks = user.favoriteBooks;
    
    return [...arr, ...favBooks.filter(el => (arr.indexOf(el.title) < 0)).map(el => el.title)];
  }, []);

console.log(books);

Upvotes: 1

Hassan Imam
Hassan Imam

Reputation: 22534

You can use array#map to get favoriteBooks of each user and then flatten it into a single array using array#concat. Then using array#map, get an array of all title.

const users = [ { name: 'Samir', age: 27, favoriteBooks:[ {title: 'The Iliad'}, {title: 'The Brothers Karamazov'} ] }, { name: 'Angela', age: 33, favoriteBooks:[ {title: 'Tenth of December'}, {title: 'Cloud Atlas'}, {title: 'One Hundred Years of Solitude'}] }, { name: 'Beatrice', age: 42, favoriteBooks:[ {title: 'Candide'} ] } ],
     titles = [].concat(...users.map(({favoriteBooks}) => favoriteBooks))
                .map(({title}) => title);
console.log(titles);

Upvotes: 0

Related Questions