JavaScript ES6: массив объектов в массиве, сгруппированный по ключу и проиндексированный по свойству - PullRequest
2 голосов
/ 01 апреля 2020

У меня есть массив объектов. Упрощенная версия (с несколькими свойствами):

let d = [
{ team:"sales", key:"employees", value:24 },
{ team:"sales", key:"floor", value:2 },
{ team:"finance", key:"employees", value:7 },
{ team:"finance", key:"floor", value:2 },
]

Хотите группировать по team, а затем по key, используя обычный (ES6) JavaScript:

{
  sales: {
    employees: { team:"sales", key:"employees", value:24 },
    floor: { team:"sales", key:"floor", value:2 }
  },
  finance: {
    employees: { team:"finance", key:"employees", value:7 },
    floor: { team:"finance", key:"floor", value:2 }
  }
}

В некоторой степени похож на другие вопросы , но не совсем.

Что у меня есть до сих пор: использование приведения к группе на team:

let groupBy = (data, field) => data.reduce((acc, obj) => Object.assign(acc, { [obj[field]]:( acc[obj[field]] || [] ).concat(obj) }), {})

let result = groupBy(d,'team')

Это дает:

{
sales: [
  { team:"sales", key:"employees", value:24 },
  { team:"sales", key:"floor", value:2 }
],
finance: [
  { team:"finance", key:"employees", value:7 },
  { team:"finance", key:"floor", value:2 }
]
}

Не уверен, каков рекомендуемый способ группировки по уровню key внутри команд.

Ответы [ 3 ]

3 голосов
/ 01 апреля 2020

Вместо накопления в массив путем объединения каждого объекта в новый массив, вы можете накопить в новый литерал объекта. Вы можете сделать это, распространяя накопленный объект в новый литерал объекта. Затем, опять же, вы можете распространить результат накопленного объекта для текущей команды объектов или взять объект по умолчанию (|| {}), если он не существует. Наконец, вы можете установить новый ключ для литерала вложенного объекта в obj.key и установить его значение в качестве самого текущего итерированного объекта.

const data = [
  { team:"sales", key:"employees", value:24 },
  { team:"sales", key:"floor", value:2 },
  { team:"finance", key:"employees", value:7 },
  { team:"finance", key:"floor", value:2 },
];

const groupBy = (array, field) => array.reduce((acc, obj) =>
  ({...acc, [obj[field]]: {...(acc[obj[field]] || {}), [obj.key]: obj}}), {});

console.log(groupBy(data,'team'));
2 голосов
/ 01 апреля 2020

Вы можете взять массив ключей для группировки и уменьшения объекта, проверив и добавив новые объекты или для последнего ключа взять объект из данных.

let d = [{ team: "sales", key: "employees", value: 24 }, { team: "sales", key:" floor", value: 2 }, { team: "finance", key: "employees", value: 7 }, { team: "finance", key: "floor", value: 2 }],
    groups = ['team', 'key'],
    result = d.reduce((acc, obj) => {
        groups.reduce((o, key, i, { length }) => {
             const k = obj[key];
             return o[k] = o[k] || (i + 1 === length ? obj : {});
        }, acc);
        return acc;
    }, {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 01 апреля 2020

Вы можете использовать уменьшить

let d = [{ team:"sales", key:"employees", value:24 },{ team:"sales", key:"floor", value:2 },{ team:"finance", key:"employees", value:7 },{ team:"finance", key:"floor", value:2 },]

let groupBy = (data, property) => data.reduce((op, inp) => {
  let prop = inp[property]
  let key = inp.key
  op[prop] = op[prop] || {}
  op[prop][key] = op[prop][key] || {}
  op[prop][key] = inp
  return op
}, {})


console.log(groupBy(d, 'team'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...