0

I tried to solve the problem on my own but I did not manage to. So I decided to ask for help.

I've got an array of JSON objects like this:

const objArr = [
 {
  name: 'Andrew',
  city: 'London'
 },
 {
  name: 'Edouard',
  city: 'Paris'
 },
 {
  name: 'Nathalie',
  city: 'London'
 },
 {
  name: 'Patrick',
  city: 'London'
 },
 {
  name: 'Mathieu',
  city: 'Paris'
 }
];

I want to gather objects with same key value - in that case the city key - in a new array to obtain this:

const newObjArr = [
 [{
  name: 'Andrew',
  city: 'London'
 },
 {
  name: 'Nathalie',
  city: 'London'
 },
{
  name: 'Patrick',
  city: 'London'
 }],
 [{
  name: 'Edouard',
  city: 'Paris'
 },
 {
  name: 'Mathieu',
  city: 'Paris'
 }]
];
3
  • Those are just arrays of objects. There's no JSON data there. Commented May 1, 2020 at 15:26
  • Wouldn't you want the resulting structure to be like this? {London: [...all the cities], Paris: [...]} Commented May 1, 2020 at 15:27
  • Ok. I just said JSON because I'm fetching an API. It gives me JSON objects. I just want to simplify my question as possible to be understable so I used name and city as keys. Let's say I don't know what the API is going to give me as city value. I just want to gather the objects with same city name together without any filter process. The resulting structure I want would be like this: [[all objects containing London], [all objects containing Paris]]. Hope I'm clear enough. Commented May 1, 2020 at 15:39

3 Answers 3

2

This is a job for .reduce().

const objArr = [
  {name: 'Andrew', city: 'London'},
  {name: 'Edouard', city: 'Paris'},
  {name: 'Nathalie', city: 'London'},
  {name: 'Patrick', city: 'London'},
  {name: 'Mathieu', city: 'Paris'}
];

// Object of arrays
const result = objArr.reduce((acc, obj) => {
  return {...acc, [obj.city]: [...acc[obj.city] || [], obj]}
}, {})

// Array of arrays
const result2 = Object.values(result);

console.log(result2)

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

1 Comment

Thank you all for those really fast answers! Now I will try to understand them.
1

Use lodash group by and then add to new array

 var objArr = [ { name: 'Andrew', city: 'London' }, { name: 'Edouard', city: 'Paris' }, { name: 'Nathalie', city: 'London' }, { name: 'Patrick', city: 'London' }, { name: 'Mathieu', city: 'Paris' } ]
 
var grouped = _.mapValues(_.groupBy(objArr, 'city'),
                          clist => clist.map(city => _.omit(city, 'city')));

 var result=[]
 for (const [key, value] of Object.entries(grouped)) {
  
  var array=[]
  value.forEach(x=>{
     array.push({ name: x.name, city:key })
  })
   result.push(array);
}
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Comments

1

You can use reduce to group by a field using that field as the key and then use Object.values if you really just want the values:

const objArr = [ { name: 'Andrew', city: 'London' }, { name: 'Edouard', city: 'Paris' }, { name: 'Nathalie', city: 'London' }, { name: 'Patrick', city: 'London' }, { name: 'Mathieu', city: 'Paris' } ];

var groupBy = function(array, k) {
  return array.reduce(function(acc, cur) {
    (acc[cur[k]] = acc[cur[k]] || []).push(cur);
    return acc;
  }, {});
};

console.log(Object.values(groupBy(objArr, 'city')));

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.