Skip to content
Advertisement

Merge properties of objects within a array together using values and remove duplicate

I would like to know how to Merge properties of objects with in same array of objects if same value in javascript.

My input data

var input = [
      { student: 'Alex', class: 'ten', subject: 'maths', marks: '85', answer: 'Moderate', percentage: '90', sports: 'good' },
    { student: 'Alex', class: 'ten', subject: 'maths', marks: '85', answer: 'Moderate', percentage: '90', sports: 'good' },
    { student: 'Alex', class: 'nine', subject: 'science', marks: '82', answer: 'Severe', percentage: '85', sports: 'good' },
    { student: 'Alex', class: 'nine', subject: 'science', marks: '82', answer: 'Severe', percentage: '85', sports: 'good' },
    { student: 'Alex', class: 'eight', subject: 'computer', marks: '90', answer: 'Extreme', percentage: '87', sports: 'good' },
    { student: 'Alex', class: 'eight', subject: 'computer', marks: '90', answer: 'Extreme', percentage: '87', sports: 'good' },
    { student: 'john', class: 'ten', subject: 'maths', marks: '90', answer: 'Extreme', percentage: '99', sports: 'good' },
    { student: 'john', class: 'ten', subject: 'maths', marks: '90', answer: 'Extreme', percentage: '99', sports: 'good' },
    { student: 'john', class: 'nine', subject: 'science', marks: '85', answer: 'Moderate', percentage: '100', sports: 'good' },
    { student: 'john', class: 'nine', subject: 'science', marks: '85', answer: 'Moderate', percentage: '100', sports: 'good' },
    { student: 'john', class: 'eight', subject: 'computer', marks: '87', answer: 'Extreme', percentage: '67', sports: 'good' },
    { student: 'john', class: 'eight', subject: 'computer', marks: '87', answer: 'Extreme', percentage: '67', sports: 'good' },
]

Expected Output:

[
   { student: 'Alex',class: 'ten', maths: '85', science: '82',computer:'90', answer: 'Moderate', percentage: '90', sports: 'good'},
    { student: 'Alex',class: 'nine', maths: '85', science: '82',computer:'90', answer: 'Moderate', percentage: '85', sports: 'good'},
    { student: 'Alex',class: 'eight', maths: '85', science: '82',computer:'90', answer: 'Moderate', percentage: '87', sports: 'good'},
    { student: 'john',class: 'ten',maths: '90', science: '85',computer:'87',answer: 'Extreme', percentage: '99', sports: 'good'},
    { student: 'john',class: 'nine',maths: '90', science: '85',computer:'87',answer: 'Extreme', percentage: '100', sports: 'good'},
    { student: 'john',class: 'eight',maths: '90', science: '85',computer:'87',answer: 'Extreme', percentage: '67', sports: 'good'},
]

I tried below code

    const output = data.reduce((a, v) => {
    const key = i.student + i.subject;
    const subjectKey = v.subject
    if (a[key]) {
        a[key] = {
            ...v,
            [subjectKey]: v.marks,
        }
    } else {
        a[key] = v
    }
    return a
}, {})
console.log(Object.values(output))

Advertisement

Answer

var input=[{student:"Alex",subject:"maths",marks:"85",answer:"Moderate"},{student:"Alex",subject:"maths",marks:"85",answer:"Moderate"},{student:"Alex",subject:"maths",marks:"85",answer:"Moderate"},{student:"Alex",subject:"science",marks:"82",answer:"Severe"},{student:"Alex",subject:"science",marks:"82",answer:"Severe"},{student:"Alex",subject:"science",marks:"82",answer:"Severe"},{student:"Alex",subject:"computer",marks:"90",answer:"Extreme"},{student:"Alex",subject:"computer",marks:"90",answer:"Extreme"},{student:"Alex",subject:"computer",marks:"90",answer:"Extreme"},{student:"john",subject:"maths",marks:"90",answer:"Extreme"},{student:"john",subject:"maths",marks:"90",answer:"Extreme"},{student:"john",subject:"maths",marks:"90",answer:"Extreme"},{student:"john",subject:"science",marks:"85",answer:"Moderate"},{student:"john",subject:"science",marks:"85",answer:"Moderate"},{student:"john",subject:"science",marks:"85",answer:"Moderate"},{student:"john",subject:"computer",marks:"87",answer:"Extreme"},{student:"john",subject:"computer",marks:"87",answer:"Extreme"},{student:"john",subject:"computer",marks:"87",answer:"Extreme"}];

//find all unique inputs, i.e. entry with unique strudent and subject
var uniqueInput = [...input].reduce((unique, obj) => {
  if (unique.filter(({student,subject}) => student === obj.student && subject === obj.subject /* && otherKeyFeatureUsedForUniqueness */).length === 0) return [...unique, obj]; //if not already inserted
    return unique; //already inserted
}, [])

var finalArray = [...uniqueInput].reduce((alreadyInsertedStudent, currentStudent) => {
    //get array of students without current student
    var arrWithoutObj = alreadyInsertedStudent.filter(({student}) => student !== currentStudent.student /* && the student or class or other properties which is constant across the duplicated rows in original input array, you can add here*/); 
    
    //if the student is not present, then withoutArray === currentarray
    //if yes, then insert the student and subject 
  if (arrWithoutObj.length === alreadyInsertedStudent.length) return [...alreadyInsertedStudent, {student: currentStudent.student, [currentStudent.subject]: currentStudent.marks, answer: currentStudent.answer/*, ...rest additional unique row defining Properties of final answer, you can add here*/}];
    //if student already inserted, then add the subject marks to that student 
    return [...alreadyInsertedStudent].map((prev) => prev.student === currentStudent.student ? {...prev, [currentStudent.subject]:currentStudent.marks} : prev);
}, [])

console.log(finalArray)
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement