根据对象数组中的相似值对对象进行分组

Group objects based on similar value in array of objects

我有一个对象数组,我想要 group/merge 具有相似分支和环境的对象并同时连接它们的池。

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",
  },
];

我想要以下格式的结果删除重复的对象我也尝试减少它但是作为数组减少returns结果是单个对象而其他对象从响应中省略了什么数据我可以用来实现结果的结构或方式?

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",
  },
];

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);

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}) 
  }
}, [])

但我建议创建一个 keys 等于分支名称的对象。

我建议为此使用 Array.reduce(),使用从 branchenvironment 创建的键创建数据映射。

一旦我们有了地图对象,我们就可以使用 Object.values() 到 return 所需结果的数组。

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; }

这是一种方法:

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)

只需根据它们创建字典并填写值即可。

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;
})

如果您不关心不变性(数据更改中的原始对象),则删除 Object.assign map 并且会产生相同的结果