robe007
robe007

Reputation: 3927

Concatenate values in same object's property inside reduce

I have an array of objects like this:

let array = [{
    "Age": 20,
    "Name": "Kevin"
}, {
    "Age": 15,
    "Name": "Alfred"
}, {
    "Age": 30,
    "Name": "Joe"
}];

I want to get an object like this:

{
    "Age": '20, 15, 30',
    "Name": 'Kevin, Alfred, Joe'
}

If I do:

let r = array.reduce(function(pV, cV) {
    Object.keys(cV).map(function(key){
        pV[key] = (pV[key] || []).concat(cV[key]);
    });
    return pV;
},{});

console.log(r); // { "Age": [20, 15, 30], "Name": ['Kevin', 'Alfred', 'Joe'] }

Or if I do:

let r = array.reduce(function(pV, cV) {
    Object.keys(cV).map(function(key){
        pV[key] = (pV[key] || '') + ', ' + cV[key];
    });
    return pV;
},{});

console.log(r); // { "Age": ', 20, 15, 30', "Name": ', Kevin, Alfred, Joe' }

I'm a little bit lost. Some ideas on how to get what I need?

Upvotes: 1

Views: 881

Answers (4)

Bergi
Bergi

Reputation: 664538

I wouldn't use reduce like that, which is just a glorified loop:

let r = {};
for (const cV of array) {
    for (const key in cV) {
        r[key] = (r[key] || []).concat(cV[key]);
    }
}

For a functional approach, where the map would be actually useful, I'd nest the iterations the other way round:

let r = {};
for (const key of ["Age", "Name"]) { // or Object.keys(array[0])
    r[key] = array.map(function(cV){
        return cV[key];
    }).join(", ");
}

Upvotes: 2

Manoj
Manoj

Reputation: 1195

You can do in this way as well.

 array.reduce((a,n)=>{
 a.Age =  a.Age+','+n.Age;
a.Name = a.Name+','+n.Name;
return a;
});

Warning!! this approach with modify actual array of object. If that is not intended then you can clone object first and then do reduce.

I did JSON.parse(JSON.stringify(array)) to clone array you can use your own ways to deep clone it.

JSON.parse(JSON.stringify(array)).reduce((a,n)=>{
 a.Age =  a.Age+', '+n.Age;
a.Name = a.Name+', '+n.Name;
return a;
}) 

Upvotes: 0

Jonas Wilms
Jonas Wilms

Reputation: 138267

You are quite close with your second appraoch, you just have to make sure that the initial , does not appear, which is quite easy with a ternary:

let r = array.reduce(function(pV, cV) {
  Object.keys(cV).map(function(key){
      pV[key] = (pV[key] ? (pV[key] + ", ") :  '') + cV[key];
  });
  return pV;
},{});

Upvotes: 3

mickl
mickl

Reputation: 49945

You can try following code using .reduce() and Object.keys

let array = [{
    "Age": 20,
    "Name": "Kevin"
}, {
    "Age": 15,
    "Name": "Alfred"
}, {
    "Age": 30,
    "Name": "Joe"
}];

let result = array.reduce((current,result) => {
	Object.keys(current).forEach(key => {
		if(!result[key]){
			result[key] = current[key];
		} else {
			result[key]+= ", " + current[key];
		}
	})
	return result;
},{});

console.log(result);

Upvotes: 2

Related Questions