Reputation: 73
I have an array of objects I want to group/merge the objects which have similar branches and environments and concat their pools at the same time.
const data = [
{
branch: "master",
environment: "dev",
pool: "6g",
service: "amex",
},
{
branch: "master",
environment: "dev",
pool: "6g",
service: "amex",
},
{
branch: "feature/rest",
environment: "dev",
pool: "2g",
service: "amex",
},
{
branch: "master",
environment: "dev",
pool: "4g",
service: "amex",
},
{
branch: "hotfix/23",
environment: "test",
pool: "9g",
service: "amex",
},
{
branch: "hotfix/23",
environment: "test",
pool: "1g",
service: "amex",
},
];
I want the result in the below format removing duplicate objects as well I tried to reduce it but as array reduce returns a single object as a result and the other objects are being omitted from the response what data structure or way I can use to achieve the result?
const result = [
{
branch: "master",
environment: "dev",
pool: "6g, 4g",
service: "amex",
},
{
branch: "feature/rest",
environment: "dev",
pool: "2g",
service: "amex",
},
{
branch: "hotfix/23",
environment: "test",
pool: "9g,1g",
service: "amex",
},
];
Upvotes: 1
Views: 111
Reputation: 1161
Just create a dictionary out of them and fill in the values.
const data=[{branch:"master",environment:"dev",pool:"6g",service:"amex"},{branch:"feature/rest",environment:"dev",pool:"2g",service:"amex"},{branch:"master",environment:"dev",pool:"4g",service:"amex"},{branch:"hotfix/23",environment:"test",pool:"9g",service:"amex"},{branch:"hotfix/23",environment:"test",pool:"1g",service:"amex"},]
let x = {};
data.forEach(y => x[y.branch + "|" + y.environment] = y);
var res = Object.values(x).map(y => Object.assign({}, y)).map(y =>
{
y.pool = data.filter(d => d.branch == y.branch && d.environment == y.environment).map(x => x.pool).join(",");
return y;
})
If you do not care about immutability(original objects in data change), then remove Object.assign map
and it will yield the same results
Upvotes: 2
Reputation: 1468
const data = [{
branch: "master",
environment: "dev",
pool: "6g",
service: "amex",
},
{
branch: "feature/rest",
environment: "dev",
pool: "2g",
service: "amex",
},
{
branch: "master",
environment: "dev",
pool: "4g",
service: "amex",
},
{
branch: "hotfix/23",
environment: "test",
pool: "9g",
service: "amex",
},
{
branch: "hotfix/23",
environment: "test",
pool: "1g",
service: "amex",
},
];
var cacheMix = {};
for (var i = 0; i < data.length; i++) {
var item = data[i];
var compositeKey = item.environment + "~" + item.branch;
if (cacheMix[compositeKey]) {
cacheMix[compositeKey].pools[item.pool] = 1;
} else {
var pools = {}; pools[item.pool] = 1; //to avoid dublicate pools
cacheMix[compositeKey] = {
branch: item.branch,
environment: item.environment,
service: item.service,
pools: pools
}
}
}
var result = [];
for (var key in cacheMix) {
var item = cacheMix[key];
result.push({
branch: item.branch,
environment: item.environment,
service: item.service,
pool: Object.keys(item.pools).join(", ")
});
}
console.log(result);
Upvotes: 5
Reputation: 1083
data.reduce((prev, curr) => {
const container = prev.find(
el => (el.branch === curr.branch) && (el.environment === curr.environment)
);
if (container) {
container.pool = container.pool + `,${curr.pool}`
return prev;
} else {
return prev.concat({...curr})
}
}, [])
but I would suggest to instead create an object with key
s equal to branch names.
Upvotes: 0
Reputation: 12209
This is one way to do it:
const data=[{branch:"master",environment:"dev",pool:"6g",service:"amex"},{branch:"feature/rest",environment:"dev",pool:"2g",service:"amex"},{branch:"master",environment:"dev",pool:"4g",service:"amex"},{branch:"hotfix/23",environment:"test",pool:"9g",service:"amex"},{branch:"hotfix/23",environment:"test",pool:"1g",service:"amex"},]
const res = data.reduce((acc, cur) =>
{
let isMatch = false
acc.forEach((el, idx) => {
if(el.branch === cur.branch && el.environment === cur.environment) {
if(acc[idx].service !== cur.service) {
acc[idx].service += `, ${cur.service}`
}
if(acc[idx].pool !== cur.pool) {
acc[idx].pool += `, ${cur.pool}`
}
isMatch = true
}
})
if(!isMatch) {
acc.push(cur)
}
return acc
}, [])
console.log(res)
Upvotes: 0
Reputation: 30685
I'd suggest using Array.reduce()
for this, creating a map of the data using a key created from the branch
and environment
.
Once we have the map object, we can use Object.values()
to return an array of the desired results.
const data = [ { branch: "master", environment: "dev", pool: "6g", service: "amex", }, { branch: "feature/rest", environment: "dev", pool: "2g", service: "amex", }, { branch: "master", environment: "dev", pool: "4g", service: "amex", }, { branch: "hotfix/23", environment: "test", pool: "9g", service: "amex", }, { branch: "hotfix/23", environment: "test", pool: "1g", service: "amex", }, ];
const result = Object.values(data.reduce((acc, { branch, environment, pool, service }) => {
// Our grouping key...
const key = `${branch}-${environment}`;
acc[key] = acc[key] || { branch, environment, pool: '', service };
acc[key].pool += ((acc[key].pool ? ", " : "" ) + pool);
return acc;
}, {}))
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }
Upvotes: 0