0

Good morning, after an array.map I have an array containing the same assignments with some nested ratings:

const assignments = [
    {
      name: "assignmentOne",
      difficultyRating: 1,
      funRating: 2
    },
    {
      name: "assignmentOne",
      difficultyRating: 3,
      funRating: 4
    },
    {
      name: "assignmentOne",
      difficultyRating: 5,
      funRating: 1
    }
]

Now I would like to get the total difficulty/fun rating, which would look like one of the following:

//Both the difficulty and fun rating in the same record
const assignmentsTotal = [
    {
      name: "assignmentOne",
      totalDifficultyRating: 9,
      totalFunRating: 7
    }
]

//Difficulty and fun rating as separate records
const assignmentsDifficultyTotal = [
    {
      name: "assignmentOne",
      totalDifficultyRating: 9
    }
]
const assignmentsFunTotal = [
    {
      name: "assignmentOne",
      totalFunRating: 7
    }
]

I'm pretty confident the best way to do this is using the reduce method. After some digging around the only thing that came close to what I want to achieve is the following article, yet I'm not able to get this to work properly. Is there a good way to do this from the starting point above, or would it be better to create separate arrays using array.map and after use the reduce method?

2
  • Hello, @ZeeAars! What code have you tried so far? Much like an educational setting, we prefer questions that show you work. Commented Dec 7, 2020 at 9:09
  • I totally forgot adding what I had tried so far, as I was trying to formulate my question as good as possible, my bad man. So far I had tried using forEach to go one level deeper and making new sets/arrays(using .map) of the data provided above, tho everything I tried either returned nan or undefined. Which I thought had something to do with all assignments having a unique name(data is a mockup JSON with 10 students with 56 assignments, all of them with a fun and difficulty rating) I will not forget to add my tests next time I want to ask a question and can still add some if you want Commented Dec 7, 2020 at 9:38

2 Answers 2

0

If you are looking for same 'name' objects in array, below should be ok:

const reducer = assignments.reduce((total, current) => {
    return { name: current.name, difficultyRating : total.difficultyRating + current.difficultyRating, funRating : total.funRating + current.funRating } });

if you want to group objects by name, then look at lodash groupby function. In general, lodash is very handy in all array/obj functionalities.

Sign up to request clarification or add additional context in comments.

7 Comments

I think you forgot to set the initial value of the accumulator for the total argument.
This worked perfectly, thanks a bunch man, both for the swift response and really clean answer :D
This solution works only if you have just one assignment (e.g. assignmentOne) but if you have more assignments (e.g. assignmentOne and assignmentTwo) it will sum the ratings of all assignments and use as name the one of the last assignment.
it worked with my array of 56 different assignments, all of them kept their original name and structure, so I'm not sure what you mean @secan
@ZeeAars, I created a code snippet to show what I mean here: jsfiddle.net/j014c67y.
|
0

const assignments = [{
    name: "assignmentOne",
    difficultyRating: 1,
    funRating: 2
  },
  {
    name: "assignmentOne",
    difficultyRating: 3,
    funRating: 4
  },
  {
    name: "assignmentOne",
    difficultyRating: 5,
    funRating: 1
  },
  {
    name: "assignmentTwo",
    difficultyRating: 5,
    funRating: 3
  },
  {
    name: "assignmentTwo",
    difficultyRating: 5,
    funRating: 1
  }
];

// if you want the totals as an array:
const assignmentsTotalArray = assignments.reduce((totalArr, item) => {
  // check whether the assignment is already in the array
  const assignmentIndex = totalArr.findIndex(elem => elem.name === item.name);

  // if the assignment is not in the array, add it and initialize the totals
  // otherwise update the totals
  if (assignmentIndex === -1) {
    totalArr.push({
      name: item.name,
      totalDifficultyRating: item.difficultyRating,
      totalFunRating: item.funRating
    });
  } else {
    totalArr[assignmentIndex].totalDifficultyRating += item.difficultyRating;
    totalArr[assignmentIndex].totalFunRating += item.funRating;
  }

  return totalArr;
}, []);

console.log('### assignmentsTotalArray:');
console.log(assignmentsTotalArray);

// if you want the totals as an object:
const assignmentsTotalObject = assignments.reduce((totalObj, item) => {
  // if the output object already contains the assignment, sum the ratings
  // otherwise create a new key for the assignment and initialize the ratings
  if (totalObj[item.name]) {
    totalObj[item.name].totalDifficultyRating += item.difficultyRating;
    totalObj[item.name].totalFunRating += item.funRating;
  } else {
    totalObj[item.name] = {
      totalDifficultyRating: item.difficultyRating,
      totalFunRating: item.funRating
    };
  }

  return totalObj;
}, {});

console.log('### assignmentsTotalObject:')
console.log(assignmentsTotalObject);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.