0

I have following array of object

let studentArray = 

[{
    "name" : "Computer Science",
    "students" : [
        {
            "student_name" : "A"
        },
        {
            "student_name" : "B"
        }
    ]
},
{
    "name" : "Math",
    "students" : [
        {
            "student_name" : "A"
        },
        {
            "student_name" : "B"
        },
        {
            "student_name" : "C"
        }
    ]
}]

and I want answer like below.

[
    {
        "student_name" : "A",
        "courses": ["Computer Science", "Math"]
    },
    {
        "student_name" : "B",
        "courses": ["Computer Science", "Math"]
    },
    {
        "student_name" : "C",
        "courses": ["Math"]
    }
]

Please help with javascript functionality and according to data structure algorithm.

I have tried below it is not working.

I there any another way to doing this Using different another loops or something another logic for that.

let studentArray = [{
      "name": "Computer Science",
      "students": [{
          "student_name": "A"
        },
        {
          "student_name": "B"
        }
      ]
    },
    {
      "name": "Math",
      "students": [{
          "student_name": "A"
        },
        {
          "student_name": "B"
        },
        {
          "student_name": "C"
        }
      ]
    }
  ]

studentArray.forEach((item, index) => {
  //console.log(item);
  if (index > 0) {
    console.log("Previous: " + studentArray[index - 1].students);
  }
  if (index < studentArray.length - 1) {
    console.log("Next: " + studentArray[index + 1].students);
  }
  //console.log(studentArray);
  console.log(item.students.filter(comparer(item.students)));
});


function comparer(otherArray) {
  return function(current) {
    return otherArray.filter(function(other) {
      return other.value == current.value && other.display == current.display
    }).length == 0;
  }
}

5
  • Please show what you have tried so far Commented Sep 8, 2021 at 12:32
  • where's the code that you wrote? Commented Sep 8, 2021 at 12:32
  • studentArray.forEach((item,index) => { //console.log(item); if (index > 0) { console.log("Previous: " + studentArray[index - 1].students); } if (index < studentArray.length - 1) { console.log("Next: " + studentArray[index + 1].students); } //console.log(studentArray); console.log(item.students.filter(comparer(item.students))); }); Commented Sep 8, 2021 at 12:35
  • function comparer(otherArray){ return function(current){ return otherArray.filter(function(other){ return other.value == current.value && other.display == current.display }).length == 0; } } @Sean Commented Sep 8, 2021 at 12:35
  • 1
    Please edit your question to add the code. Commented Sep 8, 2021 at 12:37

3 Answers 3

1

You can use Array.reduce() on the studentArray to group students with their courses.

We create an object keyed by student name and iterate over each course's student array to add students to the map (using for...each).

Finally, we use Object.values() to turn our map into an array:

const studentArray = [{ "name" : "Computer Science", "students" : [ { "student_name" : "A" }, { "student_name" : "B" } ] }, { "name" : "Math", "students" : [ { "student_name" : "A" }, { "student_name" : "B" }, { "student_name" : "C" } ] }];

const result = Object.values(studentArray.reduce((acc, course) => {
    for(let student of course.students) {
        let student_name = student.student_name;
        acc[student_name ] = acc[student_name ] || { student_name , courses: []};
        acc[student_name ].courses.push(course.name);
    }
    return acc;
}, {}))

console.log(result)

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

Comments

0

Use a nested forEach loop

const studentArray = [{
    name: "Computer Science",
    students: [{
        student_name: "A"
      },
      {
        student_name: "B"
      }
    ]
  },
  {
    name: "Math",
    students: [{
        student_name: "A"
      },
      {
        student_name: "B"
      },
      {
        student_name: "C"
      }
    ]
  }
];

const newArr = [];

studentArray.forEach((c) => {
  c.students.forEach((s) => {
    let studentIndex = newArr.findIndex(el => el.student_name === s.student_name);
    studentIndex === -1 ? newArr.push({
      student_name: s.student_name,
      courses: [c.name]
    }) : newArr[studentIndex].courses.push(c.name)
  })
})

console.log(newArr);

1 Comment

I think Terry's code will execute much faster than mine.
0

Another approach using reduce, map, and some ES6 spread syntax:

const courses = [
  {
    "name" : "Computer Science",
    "students" : [{ "student_name" : "A" }, { "student_name" : "B" }]
  },
  {
    "name" : "Math",
    "students" : [{ "student_name" : "A" }, { "student_name" : "B" }, { "student_name" : "C" }]
  }
]

// Add students from a course to an array if they're not present already
const selectUniqueStudents = (currentStudentList, course) =>
  currentStudentList.concat(course.students.filter(newStudent =>
    currentStudentList.every(
      currentStudent => currentStudent.student_name !== newStudent.student_name
    )
  ))

// Add each course that the student is on to an array and append to the    
// student object 
const addCourseDetails = (student) => ({
  ...student,
  courses: courses
    .filter(course =>
      course.students.some(courseStudent => courseStudent.student_name === student.student_name)
    )
    .map(course => course.name)
})

const transformedResult = courses
  .reduce(selectUniqueStudents, [])
  .map(addCourseDetails)

console.log(transformedResult)

// Returns:
//
//  [
//    { student_name: 'A', courses: [ 'Computer Science', 'Math' ] },
//    { student_name: 'B', courses: [ 'Computer Science', 'Math' ] },
//    { student_name: 'C', courses: [ 'Math' ] }
//  ]

Same as with Vineet's answer, Terry's would run faster. This is not as concise or easy to read either. But the demonstration of aggregate array functions and ES6 syntax might be useful.

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.