使用键将数组中的对象分组并形成新的数组对象

时间:2018-11-24 14:07:57

标签: javascript arrays

下面是我的数组对象

[{ role : 'Role 1', name: 'A', slid: 'a'}, {role : 'Role 1', name: 'B',slid: 'b'}, {role : 'Role 2', name: 'X', slid: 'x'}, {role : 'Role 2',name: 'Y', slid: 'y'},{role : 'Role 3',name: 'Z',slid: 'z'}]

如何通过使用角色来组合数组中的对象并以以下格式形成新的数组对象。

[{role : 'Role 1', list: [{name: 'A', slid: 'a'}, {name: 'B', slid: 'b'}]},
 {role : 'Role 2', list: [{name: 'X, slid: 'x'}, {name: 'Y', slid: 'y'}]},
 {role : 'Role 3', list: [{name: 'Z', slid: 'z'}]}]

我研究了许多示例,但找不到解决方案。

4 个答案:

答案 0 :(得分:3)

您可以使用reduce将数组分组为一个对象。使用Object.values将对象转换为数组。

var arr = [{"role":"Role 1","name":"A","slid":"a"},{"role":"Role 1","name":"B","slid":"b"},{"role":"Role 2","name":"X","slid":"x"},{"role":"Role 2","name":"Y","slid":"y"},{"role":"Role 3","name":"Z","slid":"z"}];

var result = Object.values(arr.reduce((c, {role,...r}) => {
  c[role] = c[role] || {role,list: []};
  c[role].list.push(r);
  return c;
}, {}));

console.log( result );

答案 1 :(得分:0)

const arr = [{
  role: 'Role 1',
  name: 'A',
  slid: 'a',
}, {
  role: 'Role 1',
  name: 'B',
  slid: 'b',
}, {
  role: 'Role 2',
  name: 'X',
  slid: 'x',
}, {
  role: 'Role 2',
  name: 'Y',
  slid: 'y',
}, {
  role: 'Role 3',
  name: 'Z',
  slid: 'z',
}];

// We go through every array element
const ret = arr.reduce((tmp, x) => {
  // Does we have already the x.role stored in our final array ?
  const elem = tmp.find(y => y.role === x.role);

  // Yes, so we push a new value inside of it
  if (elem) {
    elem.list.push({
      name: x.name,
      slid: x.slid
    });

    return tmp;
  }

  // No, so we create a new array element
  tmp.push({
    role: x.role,
    
    list: [{
      name: x.name,
      slid: x.slid
    }],
  });
  
  return tmp;
}, []);

console.log(ret);

答案 2 :(得分:0)

使用Array.map

只是一种不同的方法

let input = [{ role : 'Role 1', name: 'A', slid: 'a'}, {role : 'Role 1', name: 'B',slid: 'b'}, {role : 'Role 2', name: 'X', slid: 'x'}, {role : 'Role 2',name: 'Y', slid: 'y'},{role : 'Role 3',name: 'Z',slid: 'z'}]


let res = input.sort((a,b) => a.role.localeCompare(b.role))
               .map(({ role, ...rest }) => ({ role, list: [rest] }))
               .flatMap(({ role, list }, i, t) => 
                     role == (t[i+1] && t[i+1].role)
                       ? (t[i+1].list.unshift(list[0]), [])
                       : { role, list })

console.log(res)

答案 3 :(得分:0)

您可以使用reduce函数来解决问题

const arr = [{ role : 'Role 1', name: 'A', slid: 'a'}, {role : 'Role 1', name: 'B',slid: 'b'}, {role : 'Role 2', name: 'X', slid: 'x'}, {role : 'Role 2',name: 'Y', slid: 'y'},{role : 'Role 3',name: 'Z',slid: 'z'}]

var groupBy = function(array, key) {
  return array.reduce(function(reduceVal, obj) {
    (reduceVal[obj[key]] = reduceVal[obj[key]] || []).push(obj);
    return reduceVal;
  }, {});
};

console.log(groupBy(arr, 'role'));

//{Role 1: Array(2), Role 2: Array(2), Role 3: Array(1)}