skip to Main Content

I have the below user data.The data was nested on 2 levels and flattening it doesn’t work

[
  [
    { class_id: "Grade 1", roll_number: "1", name: "alex" },
    { class_id: "Grade 1", roll_number: "2", name: "bob" },
  ],
  [
    { class_id: "Grade 2", roll_number: "7", name: "peter" },
    { class_id: "Grade 3", roll_number: "6", name: "lia" },
    { class_id: "Grade 2", roll_number: "5", name: "mary" },
    { class_id: "Grade 3", roll_number: "1", name: "violet" },
  ],
]

Requirement is that I have to generate data taking into account of the class_id and generate information as below

[
  {
    class_id: "Grade",
    students: [
      { roll_number: "1", name: "alex" },
      { roll_number: "2", name: "boc" },
    ],
  },
  {
    class_id: "Grade 2",
    students: [
      { roll_number: "7", name: "peter" },
      { roll_number: "5", name: "mary" },
    ],
  },
  {
    class_id: "Grade 3",
    students: [
      { roll_number: "6", name: "lia" },
      { roll_number: "1", name: "violet" },
    ],
  },
]

I have tried using the below piece of code

var response = [];
data.map(item => {
  var students = [];
  for (var i = 0; i < item.length; i++) {
    const stu_obj = {
      name: item[i].name,
      roll_number: item[i].roll_number,
    };
    students.push(stu_obj);
    if (i == 0) {
      const class_obj = {
        class_id: item[0].class_id,
        studentsList: students,
      };
      response.push(class_obj);
      continue;
    }
  }
});

But it doesn’t work for cases where the item in array has multiple class_ids. What should I do?

3

Answers


  1. If you use the flat method on the data array you can iterate over the objects in the flattened array to process them.

    If you’re trying to assign things to an object with a specific id one of the simpler methods is to create an object with that id as its key name, and then assign the object you want to contain the relevant data as its value. Then, at the end of the iteration, you can grab the Object.values as an array of objects matching your criteria.

    Here’s an example using reduce.

    const data = [[{"class_id":"Grade 1","roll_number":"1","name":"alex"},{"class_id":"Grade 1","roll_number":"2","name":"bob"}],[{"class_id":"Grade 2","roll_number":"7","name":"peter"},{"class_id":"Grade 3","roll_number":"6","name":"lia"},{"class_id":"Grade 2","roll_number":"5","name":"mary"},{"class_id":"Grade 3","roll_number":"1","name":"violet"}]];
    
    // Flatten the array and then `reduce` over the
    // array. For iterated object...
    const out = data.flat().reduce((acc, c) => {
      
      // ...destructure its relevant properties
      const { class_id, roll_number, name } = c;
    
      // If a property on the accumulator doesn't exist
      // create it and assign it an object with the class_id
      // and and empty students array
      acc[class_id] ??= { class_id, students: [] };
    
      // Push an object containing the roll_number and name
      // to the students array of the corresponding object
      // identified by the class_id
      acc[class_id].students.push({ roll_number, name });
    
      // Return the accumulator for the next
      // round of iteration
      return acc;
    }, {});
    
    // Since the result of `reduce` is an object
    // use `Object.values` to get an array containing its
    // object values
    console.log(Object.values(out));
    Login or Signup to reply.
  2. You can flatten the array, then iterate over it while using an object to store an array for each class_id.

    const arr = [[{"class_id":"Grade 1","roll_number":"1","name":"alex"},{"class_id":"Grade 1","roll_number":"2","name":"bob"}],[{"class_id":"Grade 2","roll_number":"7","name":"peter"},{"class_id":"Grade 3","roll_number":"6","name":"lia"},{"class_id":"Grade 2","roll_number":"5","name":"mary"},{"class_id":"Grade 3","roll_number":"1","name":"violet"}]];
    const res = Object.entries(arr.flat().reduce((acc, {class_id, ...rest}) => {
      (acc[class_id] ??= []).push(rest);
      return acc;
    }, {})).map(([class_id, students]) => ({class_id, students}));
    console.log(res);
    Login or Signup to reply.
  3. So you want to group your students by class_id and then organize that data as an array.

    I’m not sure what the original structure is, can it only be nested 1 level deep? If so, then code like this should work:

    function groupStudentsByClass(data) {
        // Flatten the array (assumes data is only nested a single level)
        let flatData = data.flat();
    
        // Group by class_id
        const objByClassId = flatData.reduce((acc, curr) => {
            if (!acc[curr.class_id]) {
                acc[curr.class_id] = [];
            }
    
            acc[curr.class_id].push({ "roll_number": curr.roll_number, "name": curr.name });
    
            return acc;
        }, {});
    
        // Convert the object to the desired array format
        return Object.keys(objByClassId).map(class_id => {
            return { "class_id": class_id, "students": objByClassId[class_id] };
        });
    }
    
    console.log(groupStudentsByClass([
        [
            { "class_id": "Grade 1", "roll_number": "1", "name": "alex" },
            { "class_id": "Grade 1", "roll_number": "2", "name": "bob" }
        ],
        [
            { "class_id": "Grade 2", "roll_number": "7", "name": "peter" },
            { "class_id": "Grade 3", "roll_number": "6", "name": "lia" },
            { "class_id": "Grade 2", "roll_number": "5", "name": "mary" },
            { "class_id": "Grade 3", "roll_number": "1", "name": "violet" }
        ]
    ]));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search