如何使用map和reduce转换对象数组?

4

我正在尝试将 对象数组转换为不同的格式,并参考了此网址。

按多个属性对js对象进行分组 但无法解决问题。 我有一个输入 对象数组,其中包含班级和章节,我需要根据班级和章节以不同的格式转换或筛选学生。

这是我的代码 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())
    
    
    
    
    }

请提供预期输出。 - Jan Stránský
@JanStránský 在 question 中提到了预期输出.. expectedout - user5711656
最好直接将它放在这里,而不是链接中,因为链接很容易被忽略(我会把它们看作一个链接)。此外,两个链接都没有显示任何内容(两个空列)。 - Jan Stránský
2个回答

0
使用Array#reduce来构建一个包含收集数据的对象。对于每个对象,在累积的对象中查找是否存在该类别的属性。如果不存在,则创建一个并将该类别的基础结构添加到其中。 然后,在这两种情况下,都向学生数组添加一个新条目以表示该学生。
在通过此方式创建对象之后,使用Object#entries仅获取对象的值以获取最终数组。

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));


acc[cur.class].sections[0].students.push(cur); there might be multiple sections - user5711656

0

我会采取两个步骤:

  1. 重新组织值以通过索引进行映射(包括类和部分)
  2. 然后将所有内容展平到数组中;根据您要做的事情,拥有一个字典也很方便。

下面是生成字典的函数,在代码片段中还有将字典值转换为数组的第二个步骤。

    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)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接