Mam tablicę obiektów. Wersja uproszczona (z kilkoma właściwościami):

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

Chcesz pogrupować według team, a następnie według key, używając zwykłego (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 }
  }
}

Nieco podobne do innych pytań, ale nie do końca.

Co mam do tej pory: używanie redukuj do grupowania według team:

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

let result = groupBy(d,'team')

To daje:

{
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 }
]
}

Nie jestem pewien, jaki jest zalecany sposób grupowania na poziomie key wewnątrz zespołów.

2
wivku 1 kwiecień 2020, 15:14

3 odpowiedzi

Najlepsza odpowiedź

Zamiast gromadzenia danych w tablicy przez konkatenację każdego obiektu do nowej tablicy, można gromadzić dane do nowego literału obiektu. Możesz to zrobić, przenosząc zgromadzony obiekt do nowego literału obiektu. Następnie ponownie możesz rozłożyć wynik zgromadzonego obiektu dla zespołu aktualnych obiektów lub wziąć domyślny obiekt (|| {}), jeśli taki nie istnieje. Na koniec możesz ustawić nowy klucz w swoim zagnieżdżonym literale obiektu obj.key i ustawić jego wartość na sam bieżący iterowany obiekt.

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'));
3
rcoro 1 kwiecień 2020, 12:41

Możesz wziąć tablicę kluczy do grupowania i zredukować obiekt, sprawdzając i dodając nowe obiekty lub dla ostatniego klucza pobrać obiekt z danych.

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; }
2
Nina Scholz 1 kwiecień 2020, 12:25

Możesz użyć redukcji

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'))
1
Code Maniac 1 kwiecień 2020, 12:30