0

I have the following array:

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
]

I need to convert in the following format:

const a = [{
      Type: 'student',
      Names: [{
          Firstname: 'martha',
          Lastname: 'james'
        },
        {
          Firstname: 'Julie',
          Lastname: 'schrutt'
        }
      ],
    },
    {
      Type: 'Teacher',
      Names: [{
        Firstname: 'meredith',
        Lastname: 'Napier'
      }, ],
    }

I have tried lodash grouping, object.entries, array map, reduce, but not able to figure out how to do it.

2
  • You need Array#filter first and foremost. Commented May 17, 2021 at 9:46
  • 2
    Does this answer your question? How to group an array of objects by key Commented May 17, 2021 at 9:49

7 Answers 7

4

You can easily achieve this result using reduce in js.

const a = [
  {
    Name: "martha",
    Surname: "james",
    Type: "student",
  },
  {
    Name: "Meredith",
    Surname: "Napier",
    Type: "Teacher",
  },
  {
    Name: "Julie",
    Surname: "Schrutt",
    Type: "student",
  },
];

const result = a.reduce((acc, curr) => {
  const { Name, Surname, Type } = curr;
  const elSearch = acc.find((o) => o.Type === Type);
  if (elSearch) {
    elSearch.Names.push({
      Firstname: Name,
      Lastname: Surname,
    });
  } else {
    acc.push({
      Type,
      Names: [
        {
          Firstname: Name,
          Lastname: Surname,
        },
      ],
    });
  }
  return acc;
}, []);

console.log(result);

You can make the above code snippet shorter if you change the name of the variable while destructuring

const { Name: Firstname, Surname: Lastname, Type } = curr;

and use it as

elSearch.Names.push({ Firstname, Lastname });

const a = [
  { Name: "martha", Surname: "james", Type: "student"},
  { Name: "Meredith", Surname: "Napier", Type: "Teacher"},
  { Name: "Julie", Surname: "Schrutt", Type: "student"},
];

const result = a.reduce((acc, curr) => {
  const { Name: Firstname, Surname: Lastname, Type } = curr;
  const elSearch = acc.find((o) => o.Type === Type);
  if (elSearch) {
    elSearch.Names.push({ Firstname, Lastname });
  } else {
    acc.push({ Type, Names: [{ Firstname, Lastname }] });
  }

  return acc;
}, []);

console.log(result);

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

2 Comments

can you explain what is the need for elSearch?
As the end result will be stored in [] you need to find the element in that array so that you can push the element/object in its Names.
1

use this method for any group by :

const groupBy = function (list, key) {
  return list.reduce((finalList, item) => {
    const group = (finalList[item[key]] = finalList[item[key]] || [])
    group.push(item)
    return finalList
  }, {})
}

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
]

console.log(groupBy(a, 'Type'))

Comments

0

Using forEach:

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
];

const out = [{Type: 'student', Names: []}, {Type: 'teacher', Names: []}];
a.forEach(a => {
  if (a.Type === 'student')
    return out[0].Names.push({
        Firstname: a.Name,
        Lastname: a.Surname,
    });
  out[1].Names.push({
      Firstname: a.Name,
      Lastname: a.Surname,
  });
});

console.log(out);

Comments

0

Try something like this:

const output = {};    

for(const person of array) {
    if(!output[person.Type]) output[person.Type] = { Type: person.Type, Names:[] };
    output[person.Type].Names.push({ Firstname: person.Name, Lastname: person.Surname });
}

return Object.values(output);

Or in short:

Object.values(array.reduce((pre, curr) => {
    if(!pre[curr.Type]) pre[curr.Type] = { Type: curr.Type, Names:[] };
    pre[curr.Type].Names.push({ Firstname: curr.Name, Lastname: curr.Surname });
    return pre;
} , {}))

Comments

0

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
]

const types = a.reduce((acc, next) => {
    if (acc.includes(next.Type)) {
    return acc
  }
  return acc.concat(next.Type)
}, [])

const arrayByTypes = types.map((type) => {
    return {
    Type: type,
    Names: a.filter(item => item.Type === type).map(filtered => ({ Name: filtered.Name, Surname: filtered.Surname }))
    }
})

console.log(arrayByTypes)

Comments

0
const data = [{
        Name: 'martha',
        Surname: 'james',
        Type: 'student',
    },
    {
        Name: 'Meredith',
        Surname: 'Napier',
        Type: 'Teacher',
    },
    {
        Name: 'Julie',
        Surname: 'Schrutt',
        Type: 'student',
    }
]

function processData(data) {
    finalMap = new Map();
    data.forEach((obj) => {
        let typeName = obj["Type"];
        let firstName = obj["Name"];
        let lastName = obj["Surname"];
        if (!finalMap[typeName]) {
            finalMap[typeName] = [];
        }
        finalMap[typeName].push({
            "Firstname": firstName,
            "LastName": lastName
        });
    });
    let result = [];
    for (const [key, value] of Object.entries(finalMap)) {
        result.push({
            "Type": key,
            "Names": value
        });
    }
    return result;

}
console.log(processData(data));

Comments

0

We can use Array.reduce & Object.values in order to achieve the expected output.

const a = [{Name:'martha',Surname:'james',Type:'student'},{Name:'Meredith',Surname:'Napier',Type:'Teacher'},{Name:'Julie',Surname:'Schrutt',Type:'student'}];

const groupBy = (data, by) => {
  const result = data.reduce((acc, obj) => {
    const key = obj[by];
    const { Type, Name: Firstname, Surname: Lastname } = obj;
    acc[key] = acc[key] || { Type, Names: []};
    acc[key].Names.push({ Firstname, Lastname });
    return acc;
  }, {});
  return Object.values(result);
}

console.log(groupBy(a, "Type"));
.as-console-wrapper {
  max-height: 100% !important;
}

We can also use Logical nullish assignment (??=) instead of acc[obj[by]] = acc[obj[by]] || { Type, Names: []}

const a = [{Name:'martha',Surname:'james',Type:'student'},{Name:'Meredith',Surname:'Napier',Type:'Teacher'},{Name:'Julie',Surname:'Schrutt',Type:'student'}];

const groupBy = (data, by) => {
  const result = data.reduce((acc, obj) => {
    const key = obj[by];
    const { Type, Name: Firstname, Surname: Lastname } = obj;
    acc[key] ??= { Type, Names: []};
    acc[key].Names.push({ Firstname, Lastname });
    return acc;
  }, {});
  return Object.values(result);
}

console.log(groupBy(a, "Type"));
.as-console-wrapper { 
  max-height: 100% !important;
}

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.