AJSwift
AJSwift

Reputation: 719

array reduce accumulator as an empty array, push not working

Why is the accumulator.push not valid? accumulator is an empty array!? If i use the predefined variable flarArray, things work just fine!! I know that if no initial value is included in the reduce callback, then it will use the first item in the array (which in my case will be an object) to be the accumulator, but if I tell it to start off as an array as the accumulator, what is the problem with that?

const profiles = [
  {
    id: 1,
    userID: '1',
    favoriteMovieID: '1',
  },
  {
    id: 2,
    userID: '2',
    favoriteMovieID: '1',
  }
];

const users = {
  1: {
    id: 1,
    name: 'Jane Cruz',
    userName: 'coder',
  },
  2: {
    id: 2,
    name: 'Matthew Johnson',
    userName: 'mpage',
  }
};

const movies = {
  1: {
    id: 1,
    name: 'Planet Earth 1',
  },
  2: {
    id: 2,
    name: 'Selma',
  }
};
let flatArray = [];
const flattenedProfiles = profiles.reduce(function(accumulator, currentProfile) {  
  return accumulator.push({id: currentProfile.id, name: users[currentProfile.id].name, favoriteMovie: movies[currentProfile.favoriteMovieID].name})
},[]);

Upvotes: 0

Views: 2814

Answers (3)

Ashish
Ashish

Reputation: 4330

Array.push returns the new length of the array when inside the return of callback of reduce you are returning the new length on which you can't do next push operation. Use Array.concat instead or after Array.push also return the array.

const flattenedProfilesPush = profiles.reduce((acc, curr) => {  
    acc.push({
        id: curr.id,
    })
    return acc
},[])


const flattenedProfilesConcat = profiles.reduce((acc, curr) =>  
    acc.concat({
        id: curr.id,
    }),[]
)

Upvotes: 2

Yousaf
Yousaf

Reputation: 29282

You need to return accumulator, instead you are returning the return value of push function which is the size of the array after adding the new item. In next iteration, you are calling push function on an integer

const flattenedProfiles = profiles.reduce((acc, curr) => {  
  acc.push({
     id: curr.id,
     name: users[curr.id].name,
     favoriteMovie: movies[curr.favoriteMovieID].name
  });

  return acc;
},[]);

Upvotes: 4

Ilijanovic
Ilijanovic

Reputation: 14904

The problem is you return accumulator.push(). This returns the length of the array, so your next accumulator is gonna be a number instead of an array.

I would better return an array and use spread operator on the accumulator.

const profiles = [
  {
    id: 1,
    userID: '1',
    favoriteMovieID: '1',
  },
  {
    id: 2,
    userID: '2',
    favoriteMovieID: '1',
  }
];

const users = {
  1: {
    id: 1,
    name: 'Jane Cruz',
    userName: 'coder',
  },
  2: {
    id: 2,
    name: 'Matthew Johnson',
    userName: 'mpage',
  }
};

const movies = {
  1: {
    id: 1,
    name: 'Planet Earth 1',
  },
  2: {
    id: 2,
    name: 'Selma',
  }
};
let flatArray = [];
const flattenedProfiles = profiles.reduce(function(accumulator, currentProfile) {  
  return [...accumulator, {id: currentProfile.id, name: users[currentProfile.id].name, favoriteMovie: movies[currentProfile.favoriteMovieID].name}]
},[]);

console.log(flattenedProfiles);

Upvotes: 1

Related Questions