skip to Main Content

Here is my student score json file :
(the idea is creating a function to change specific student score)

const classesData = [
  {
    name: 'A',
    books: [
      { name: 'math' },
      { name: 'chemistry' },
      { name: 'physic' }
    ],
    students: [
      {
        name: 'first student',
        results: [
          { name: 'math', score: '20' },
          { name: 'chemistry', score: '14' },
          { name: 'physic', score: '16' },
        ]
      },
      {
        name: 'second student',
        results: [
          { name: 'math', score: '15' },
          { name: 'chemistry', score: '10' },
          { name: 'physic', score: '12' },
        ]
      }
    ]
  },
  {
    name: 'B',
    books: [
      { name: 'math' },
      { name: 'chemistry' },
      { name: 'physic' }
    ],
    students: [
  {
        name: 'first student',
        results: [
          { name: 'math', score: '20' },
          { name: 'chemistry', score: '14' },
          { name: 'physic', score: '16' },
        ]
      },
      {
        name: 'second student',
        results: [
          { name: 'math', score: '15' },
          { name: 'chemistry', score: '10' },
          { name: 'physic', score: '12' },
        ]
      }
    ]
  }
]

How to do that?
For example
from class A change second student physic score to from 12 to 20
I’ve tried foreach and map but I didn’t get the result that I want

2

Answers


  1. To write a function that updates the score of a specific Student for a specific subject, we should pass the five parameters to the function:

    function patchScore(data, letterClass, student, subject, score) {}
    

    For convenience, we will return the changed data.

    Below an implementation, you could write it shorter but I preferred readability. Keep in mind I only follow the ‘happy path’ and you should best add some validation if (for example) a student is not found.

    const classesData = [
      {
        name: 'A',
        books: [
          { name: 'math' },
          { name: 'chemistry' },
          { name: 'physic' }
        ],
        students: [
          {
            name: 'first student',
            results: [
              { name: 'math', score: '20' },
              { name: 'chemistry', score: '14' },
              { name: 'physic', score: '16' },
            ]
          },
          {
            name: 'second student',
            results: [
              { name: 'math', score: '15' },
              { name: 'chemistry', score: '10' },
              { name: 'physic', score: '12' },
            ]
          }
        ]
      },
      {
        name: 'B',
        books: [
          { name: 'math' },
          { name: 'chemistry' },
          { name: 'physic' }
        ],
        students: [
      {
            name: 'first student',
            results: [
              { name: 'math', score: '20' },
              { name: 'chemistry', score: '14' },
              { name: 'physic', score: '16' },
            ]
          },
          {
            name: 'second student',
            results: [
              { name: 'math', score: '15' },
              { name: 'chemistry', score: '10' },
              { name: 'physic', score: '12' },
            ]
          }
        ]
      }
    ]
    
    let patchedData = patchScore(classesData, 'A', 'first student', 'math', 1);
    console.log(patchedData)
    
    function patchScore(data, letterClass, student, subject, score) {
    
      // Select correct class
      let filteredData = data.find((d) => d.name === letterClass)
    
      // Find student
      let matchedStudent = filteredData.students.find((s) => s.name === student)
      
      // Find subject
      let matchedSubject = matchedStudent.results.find((s) => s.name === subject)
      
      // Update score
      matchedSubject.score = score
      
      return data;
      
    }
    Login or Signup to reply.
  2. Here’s a solution to change the score for a specific student in a specific class. I’ll show you how to do it with a pure JavaScript function first, and then I’ll use Lodash. You can create a copy of the classesData array, update the score for the specific student, and return the modified copy without affecting the original data.

    1. Pure JavaScript Solution (with immutability):
      You can use map to create a new copy of the array and update the student’s score on this new copy without affecting the original data;
    const classesData = [
      {
        name: 'A',
        books: [
          { name: 'math' },
          { name: 'chemistry' },
          { name: 'physic' }
        ],
        students: [
          {
            name: 'first student',
            results: [
              { name: 'math', score: '20' },
              { name: 'chemistry', score: '14' },
              { name: 'physic', score: '16' },
            ]
          },
          {
            name: 'second student',
            results: [
              { name: 'math', score: '15' },
              { name: 'chemistry', score: '10' },
              { name: 'physic', score: '12' },
            ]
          }
        ]
      },
      {
        name: 'B',
        books: [
          { name: 'math' },
          { name: 'chemistry' },
          { name: 'physic' }
        ],
        students: [
      {
            name: 'first student',
            results: [
              { name: 'math', score: '20' },
              { name: 'chemistry', score: '14' },
              { name: 'physic', score: '16' },
            ]
          },
          {
            name: 'second student',
            results: [
              { name: 'math', score: '15' },
              { name: 'chemistry', score: '10' },
              { name: 'physic', score: '12' },
            ]
          }
        ]
      }
    ]
    
    
    
    function updateStudentScore(className, studentName, subjectName, newScore) {
      // Deep copy the classesData to avoid modifying the original
      const newClassesData = classesData.map(cls => {
        if (cls.name === className) {
          return {
            ...cls,
            students: cls.students.map(student => {
              if (student.name === studentName) {
                return {
                  ...student,
                  results: student.results.map(result => {
                    if (result.name === subjectName) {
                      return { ...result, score: newScore };
                    }
                    return result;
                  })
                };
              }
              return student;
            })
          };
        }
        return cls;
      });
    
      return newClassesData;
    }
    
    // Example: Update second student's physics score in class A to 20
    const updatedData = updateStudentScore('A', 'second student', 'physic', '20');
    
    console.log(updatedData);
    1. Lodash Solution (with immutability):
      Lodash provides utility functions like cloneDeep to easily make deep copies of objects Here’s the Lodash approach to achieve the same goal:
    const _ = require('lodash');
    
    function updateStudentScoreWithLodash(className, studentName, subjectName, newScore) {
      // Deep clone the original array to avoid modifying it
      const newClassesData = _.cloneDeep(classesData);
    
      // Find the class, student, and result, and modify the cloned data
      const classObj = _.find(newClassesData, { name: className });
      if (!classObj) return newClassesData;
    
      const student = _.find(classObj.students, { name: studentName });
      if (!student) return newClassesData;
    
      const result = _.find(student.results, { name: subjectName });
      if (result) {
        _.set(result, 'score', newScore);
      }
    
      return newClassesData;
    }
    
    // Example: Update second student's physics score in class A to 20
    const updatedData = updateStudentScoreWithLodash('A', 'second student', 'physic', '20');
    
    console.log(updatedData);
    
    

    Explanation:
    In both examples, we first create a deep copy of the original classesData to prevent modifying it directly.

    1. Find the class: Using find to search the classesData array by class name.

    2. Find the student: Inside the class, use find again to locate the student.

    3. Update the score: Search the student’s results array to locate the correct subject and update the score.

    Pure JavaScript functions solution

    we use map and the spread operator (...) to create new copies of the objects and update the score.

    Lodash solution

    _.cloneDeep creates the deep copy, and _.find is used to locate the class, student, and result, while _.set updates the score.
    Both solutions ensure the original data remains unaltered, and you get a modified copy of classesData.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search