简体   繁体   中英

how to transform array of object using reduce of map?

I am trying to transform array of object to different format.I also take reference from this url

Group js objects by multiple properties But not able to solve the problem I have a input array of object which have class and sections I need to transform or filter student in different format on basis of class and section.

here is my code https://jsbin.com/nidudisuza/edit?js,output

    let expectedout = [
      
      {
    
            class: 1,
            sections: [{
                "section": "B",
                students: [ {
            "name": "Test",
            "class": 1,
            "gender": "M",
            "section": "B",
            "rollNumber": "123111",
            "sports": [
                "Badminton",
                "Chess"
            ],
            "age": 7
        }]
            }]
    
        },
      {
    
            class: 3,
            sections: [{
                "section": "B",
                students: [{
                    "name": "Rahul",
                    "class": 3,
                    "gender": "M",
                    "section": "B",
                    "rollNumber": "1231",
                    "sports": [
                        "Badminton",
                        "Chess"
                    ],
                    "age": 7
                }]
            }]
    
        },
    
        {
            class: 5,
            sections: [{
                "section": "C",
                students: [
    
                    {
                        "name": "Rajat",
                        "class": 5,
                        "gender": "M",
                        "section": "C",
                        "rollNumber": "123122",
                        "sports": [
                            "Chess"
                        ],
                        "age": 9
                    }
    
                ]
            }]
    
        }
    
    ]
    
    const input = [{
            "name": "Rahul",
            "class": 3,
            "gender": "M",
            "section": "B",
            "rollNumber": "1231",
            "sports": [
                "Badminton",
                "Chess"
            ],
            "age": 7
        },
        {
            "name": "Rajat",
            "class": 5,
            "gender": "M",
            "section": "C",
            "rollNumber": "123122",
            "sports": [
                "Chess"
            ],
            "age": 9
        },
        {
            "name": "Test",
            "class": 1,
            "gender": "M",
            "section": "B",
            "rollNumber": "123111",
            "sports": [
                "Badminton",
                "Chess"
            ],
            "age": 7
        },
    ]
    
    function abc() {
    //     let output =
    //         data.map((i) => {
    //             let obj = {};
    //             obj.class = i.class;
    //             obj.sections = [];
              
    //           obj.sections.push({
    //             section:obj.section,
    //             students:[obj]
                
    //           })
    
    //           return obj;
    //         })
      
        let output =input.reduce((acc,i)=>{
              let cls = i.class;
              const found = acc.some(el => el.class === cls);
              let obj = {
                section:i.section,
                students:[]
              }
              found.sections.students.push[i]
    
            },[])

return output
    
    }
    
    console.log(abc())
    
    
    
    
    }

Using Array#reduce to build an Object with the collected data. Foreach object look in the accumulated object if there exists an prperty for this class. If not create one and add to this the groundstructure for this class. Afterwards add in both cases to the students array a new entry for this student.
After creating by this the object use Object#entries to take only the values of the object to get the ished array.

 function modify(data) { let res= Object.values(data.reduce((acc, cur) => { if (.acc[cur.class]) { acc[cur:class] = { class. cur,class: sections: [{ "section". cur,section: students; [] }] }. } acc[cur.class].sections[0].students;push(cur); return acc, };{})); return res: } const data = [{ "name", "Rahul": "class", 3: "gender", "M": "section", "B": "rollNumber", "1231": "sports", [ "Badminton", "Chess" ]: "age", 7 }: { "name", "Rajat": "class", 5: "gender", "M": "section", "C": "rollNumber", "123122": "sports", [ "Chess" ]: "age", 9 }: { "name", "Test": "class", 1: "gender", "M": "section", "B": "rollNumber", "123111": "sports", [ "Badminton", "Chess" ]: "age", 7 }. ] console;log(modify(data));

I'd go for a 2 step process:

  1. Reorganize the values to be mapped by an index (both for class and sections)
  2. Then flatten out everything in arrays; depending on what you're doing having a dictionary could also be convenient.

Below you can find the function that makes the dictionary, in the snippet there is also the second step that transforms the dictionary values in arrays.

    function abc() {
       let output = input.reduce((ac, x) => {
       let keyCl = x.class
       let keySec = x.section
       let orgClass = ac[keyCl]
       let sections = orgClass && orgClass.sections || {}
       let oldSec = sections && sections[keySec]
       let sectionBase = oldSec || {
         section: keySec,
         students: []
       }
       sectionBase.students = [...(oldSec ? .students || []), x]

       return {
         ...ac,
         // we organize classes to be indexed in an obj,
         // we can flat this out later
         [keyCl]: {
           class: keyCl,
           sections: {
             ...sections,
             // like for classes we organize sections by key
             [keySec]: sectionBase
           }
         }
       }
     }, {})
     return output
    }

 let expectedout = [{ class: 1, sections: [{ "section": "B", students: [{ "name": "Test", "class": 1, "gender": "M", "section": "B", "rollNumber": "123111", "sports": [ "Badminton", "Chess" ], "age": 7 }] }] }, { class: 3, sections: [{ "section": "B", students: [{ "name": "Rahul", "class": 3, "gender": "M", "section": "B", "rollNumber": "1231", "sports": [ "Badminton", "Chess" ], "age": 7 }] }] }, { class: 5, sections: [{ "section": "C", students: [ { "name": "Rajat", "class": 5, "gender": "M", "section": "C", "rollNumber": "123122", "sports": [ "Chess" ], "age": 9 } ] }] } ] const input = [{ "name": "Rahul", "class": 3, "gender": "M", "section": "B", "rollNumber": "1231", "sports": [ "Badminton", "Chess" ], "age": 7 }, { "name": "Rajat", "class": 5, "gender": "M", "section": "C", "rollNumber": "123122", "sports": [ "Chess" ], "age": 9 }, { "name": "Test", "class": 1, "gender": "M", "section": "B", "rollNumber": "123111", "sports": [ "Badminton", "Chess" ], "age": 7 }, ] function abc() { let output = input.reduce((ac, x) => { let keyCl = x.class let keySec = x.section let orgClass = ac[keyCl] let sections = orgClass && orgClass.sections || {} let oldSec = sections && sections[keySec] let sectionBase = oldSec || { section: keySec, students: [] } sectionBase.students = [...(oldSec && oldSec.students || []), x] return {...ac, // we organize classes to be indexed in an obj, // we can flat this out later [keyCl]: { class: keyCl, sections: {...sections, // like for classes we organize sections by key [keySec]: sectionBase } } } }, {}) return output } let res = abc() console.log('with keys', res) let onlyValues = Object.values(res).map(x => ({...x, sections: Object.values(x.sections) })) console.log('only values', onlyValues)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM