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})
},[]);
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})
},[]);
Share
Improve this question
asked May 28, 2020 at 13:41
AJSwiftAJSwift
7294 gold badges14 silver badges26 bronze badges
1
-
3
The
push()
method returns the new length of the array, so in your callback you're returning an integer instead of the accumulator. You need to changereturn accumulator.push({ ... })
intoaccumulator.push({ ... }); return accumulator;
– Lennholm Commented May 28, 2020 at 13:45
3 Answers
Reset to default 4You 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;
},[]);
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,
}),[]
)
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);